首页 > 其他分享 >CF163E e-Government 题解

CF163E e-Government 题解

时间:2024-08-22 21:26:43浏览次数:7  
标签:1000010 cnt struct Government int 题解 del ed CF163E

题目传送门

前置知识

AC 自动机 | 树状数组

解法

一次性将所有模式串加入 AC 自动机,然后处理加入和删除,考虑单次操作对答案的贡献。

因为模式串 \(T\) 在文本串 \(S\) 中出现的次数之和等价于 \(T\) 在 \(S\) 的所有前缀中作为后缀出现的次数之和。这就很和 \(fail\) 树上跳到根节点的性质相符。

加入/删除分别对应末尾标记 \(ed\) 的 \(+1/-1\)。

单点修改加一个点到根节点这条链的区间查询可以转化为子树修改加单点查询。

转成 DFS 序后树状数组维护即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
struct node
{
	int nxt,to;
}e[1000010];
int head[1000010],dfn[1000010],out[1000010],del[1000010],tot=0,cnt=0;
char s[1000010];
void add(int u,int v)
{
	cnt++;
	e[cnt].nxt=head[u];
	e[cnt].to=v;
	head[u]=cnt;
}
struct BIT
{
	int c[1000010];
	int lowbit(int x)
	{
		return x&(-x);
	}
	void add(int n,int x,int val)
	{
		for(int i=x;i<=n;i+=lowbit(i))
		{
			c[i]+=val;
		}
	}
	void update(int n,int l,int r,int val)
	{
		add(n,l,val);
		add(n,r+1,-val);
	}
	int getsum(int x)
	{
		int ans=0;
		for(int i=x;i>=1;i-=lowbit(i))
		{
			ans+=c[i];
		}
		return ans;
	}
}B;
struct ACM
{
	int ed[1000010],fail[1000010],rt_sum;
	struct trie
	{
		int ch[27];
	}tree[1000010];
	int val(char x)
	{
		return x-'a'+1;
	}
	void insert(char s[],int len,int id)
	{
		int x=0;
		for(int i=1;i<=len;i++)
		{
			if(tree[x].ch[val(s[i])]==0)
			{
				rt_sum++;
				tree[x].ch[val(s[i])]=rt_sum;
			}
			x=tree[x].ch[val(s[i])];
		}
		ed[id]=x;
	}
	void build()
	{
		queue<int>q;
		for(int i=1;i<=26;i++)
		{
			if(tree[0].ch[i]!=0)
			{
				fail[tree[0].ch[i]]=0;
				add(0,tree[0].ch[i]);
				q.push(tree[0].ch[i]);
			}
		}
		while(q.empty()==0)
		{
			int x=q.front();
			q.pop();
			for(int i=1;i<=26;i++)
			{
				if(tree[x].ch[i]==0)
				{
					tree[x].ch[i]=tree[fail[x]].ch[i];
				}
				else
				{
					fail[tree[x].ch[i]]=tree[fail[x]].ch[i];
					add(fail[tree[x].ch[i]],tree[x].ch[i]);
					q.push(tree[x].ch[i]);
				}
			}
		}	
	}
	int query(char s[],int len)
	{
		int x=0,ans=0;
		for(int i=1;i<=len;i++)
		{
			x=tree[x].ch[val(s[i])];
			ans+=B.getsum(dfn[x]);
		}
		cerr<<endl;
		return ans;
	}
}A;
void dfs(int x)
{
	tot++;
	dfn[x]=tot;
	for(int i=head[x];i!=0;i=e[i].nxt)
	{
		dfs(e[i].to);
	}
	out[x]=tot;
}
int main()
{
	int q,n,x,i;
	char pd;
	cin>>q>>n;
	for(i=1;i<=n;i++)
	{
		cin>>(s+1);
		A.insert(s,strlen(s+1),i);
	}
	A.build();
	dfs(0);
	for(i=1;i<=n;i++)
	{
		B.update(tot,dfn[A.ed[i]],out[A.ed[i]],1);
	}
	for(i=1;i<=q;i++)
	{
		cin>>pd;
		if(pd=='?')
		{
			cin>>(s+1);
			cout<<A.query(s,strlen(s+1))<<endl;
		}
		if(pd=='+')
		{
			cin>>x;
			if(del[x]==1)
			{
				del[x]=0;
				B.update(tot,dfn[A.ed[x]],out[A.ed[x]],1);
			}
		}
		if(pd=='-')
		{
			cin>>x;
			if(del[x]==0)
			{
				del[x]=1;
				B.update(tot,dfn[A.ed[x]],out[A.ed[x]],-1);
			}
		}
	}
	return 0;
}

标签:1000010,cnt,struct,Government,int,题解,del,ed,CF163E
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18374806

相关文章

  • [题解] permutation
    [题解]Permutation解析一眼DP或者组合。70pts场上推的DP对于\((4,2,2)\),先把所有序列枚举出来:\[\begin{split}1\\\2\\1\\\3\\1\\\4\\--\\2\\\3\\2\\\4\\3\\\4\end{split}\]可以发现,对于分割线上的部分,可以看作\((3,1,1)\)的所有序列......
  • csp模拟27-金箱子(题解)
    题目链接(显然还没有找到原题)虽说我现在才学会期望dp显得不太好,但没办法,谁让我比较菜~~,之前模拟赛已经考过几道类似的题了,但都一笔带过了,这次算是正式学习了一下这类题,于是就有了这篇题解。首先看到k次方首先想到的就是我们在进行dp转移的时候不太方便,这个时候很自然的想到二项......
  • 题解:P9041 [PA2021] Fiolki 2
    \(\text{Link}\)题意给定一个\(n\)个点\(m\)条边的DAG,定义\(f(l,r)\)表示最多选取多少条不相交路径\((s_i,t_i)\)满足\(s_i\in[1,k],t_i\in[l,r]\),其中不能有任意一点同时在两条选出的路径上。对\(\forallx\in[0,k)\)求出有多少\([l,r]\sube(k,n]\)使得\(f(l,r)......
  • 题解:P10881「KDOI-07」能量场
    \(\text{Link}\)题意给你一个长为\(n\)的序列\(a_{1\dotsn}\),定义一条边\((u,v)\)的权值为\(a_u+a_v\)。对于一张图,定义其权值为包含的所有边的权值乘积。求所有\(n\)个点的有标号基环树的权值之和。对\(998244353\)取模。\(n\le10^3\)。思路非常厉害的题,zky倾......
  • 题解:P10698 [SNCPC2024] 最大流
    \(\text{Link}\)题意给定一个\(n\)个点\(m\)条边的单位网络,保证该网络不存在环。给定一个常数\(k\),设从\(1\)到\(i\)的最大流为\(f_i\),对\(\foralli\in[2,n]\)求出\(\min(f_i,k)\)。\(n\le10^5\),\(m\le2\times10^5\),\(k\le\min(n-1,50)\)。思路不相交路径,考......
  • 升级Openssh 后 最大文件打开数修改不生效,启动 UsePAM yes后 ,最大文件打开数生效但是
    感谢 博主https://blog.csdn.net/Daphnisz/article/details/124040904vi /etc/pam.d/sshd(注意不是/etc/pam.d/sshd.pam)#%PAM-1.0auth required pam_sepermit.soauthsubstackpassword-authauthincludepostlogin#Usedwithpolkittoreauthor......
  • 常见问题解决 --- 为什么我们常常发现服务器没有管理的端口
    我们在扫描一台主机全端口,发现没有开放管理端口,比如windows远程桌面或者是linux的ssh登陆。我列举一下常见的原因。常规管理方式:1.管理口不是常见的3389和22端口,而改为了高位端口号,避免被人发现。2.在管理端口上加上了安全策略导致无法直接连接,比如私钥登陆方......
  • 题解:CF1986B Matrix Stabilization
    洛谷传送门题意一个\(n\timesm\)的矩阵,依次进行以下操作:从\((1,1)\)开始遍历矩阵,找到最小的\((i,j)\)满足\(a{i,j}\)的值严格大于其所有相邻(四联通)单元格的值,如果没有则退出将1操作找到的\(a_{i,j}-1\)返回1操作求最后的矩阵。思路模拟,我们按照题目所说,从......
  • 题解:P7020 [NWRRC2017] Boolean Satisfiability
    题目传送门题目大意给定一个由大小写字母(变量),|和~组成的布尔代数式,变量可以任意赋值为True或False。求对于给定的变量,有多少种赋值方案使得给定的代数式值为True。思路一个一个看,首先考虑|,先假设只有|,则当代数式中有一个变量为True时,代数式的值变为True。因为每一......
  • 题解:P9788 [ROIR 2020 Day2] 区域规划
    题目传送门思路首先我们看下数据范围,$n<=3000$,范围很小,所以暴力枚举。于是第一份代码出来了。#include<bits/stdc++.h>usingnamespacestd;ints,a,b,c,d,n,m;intmain(){ ios::sync_with_stdio(false); cin.tie(),cout.tie(); cin>>n>>m; for(a=1;a<=n;a++) {......