BZOJ4896 [Thu Summer Camp2016]补退选

 

zz:https://www.cnblogs.com/ljh2000-jump/p/6880362.html

 考虑每次加入删除对出现次数的影响只会加减一,那么我可以先用Trie来维护整个问题中出现的字符串,然后对于每个节点我都记录一下以当前串为前缀的字符串个数,同时开个vector维护出现次数为x时的最早时刻。因为每次修改只会加减一,那么空间与字符串长度同级,这个用vector实现很方便。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
const int MAXN = 100011;
int n,ch[MAXN*60][10],c[MAXN*60],len,S,cnt,ans;
char s[MAXN];
vectorw[MAXN*60];
 
inline int getint()
{
    int w=0,q=0; 
	char c=getchar(); 
	while((c<'0'||c>'9') && c!='-') 
	      c=getchar();
    if(c=='-') 
	q=1,c=getchar(); 
	while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
}
 
inline void work()
{
    n=getint(); 
	S=cnt=1; 
	int type,u,now; 
	LL x,A,B,C;
    for(int o=1;o<=n;o++) 
	{
        type=getint(); 
		u=S;
        scanf("%s",s); 
		len=strlen(s);
        if(type==1) 
		{
            for(int i=0;i(int)w[u].size()) 
                //记下每个前缀首次出现某个次数时的时间 
				    w[u].push_back(o);
            }
        }
        else if(type==2) 
		{
            for(int i=0;i 
 

  

 

#include
#include
#include
#include
#include
using namespace std;
#define N 100050
#define M 6000050
int n,ans=0;
char s[65];
struct Trie
{
    int tot,siz[M],ch[M][12];
    vectorv[M];
    void insert(int k)
    {
        int len = strlen(s+1),u=0;
        for(int i=1;i<=len;i++)
        {
            siz[u]++;
            if(v[u].size() 
 

  

你可能感兴趣的:(BZOJ4896 [Thu Summer Camp2016]补退选)