zoukankan      html  css  js  c++  java
  • bzoj2555 SubString

    https://www.lydsy.com/JudgeOnline/problem.php?id=2555
    想一下sam求子串出现次数的方法基本就能得到正解。
    由于子串出现次数是一个子树和的形式。
    动态插入字符串又要求动态维护树的结构,显然要用LCT。
    注意一下LCT维护子树和的写法即可。

    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<cstdlib>
    #include<algorithm>
    #define N 1500000
    #define eps 1e-7
    #define inf 1e9+7
    #define db double
    #define ll long long
    #define ldb long double
    using namespace std;
    inline int read()
    {
    	char ch=0;
    	int x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*flag;
    }
    #define lson son[x][0]
    #define rson son[x][1]
    int v[N],sz[N],sw[N],st[N],f[N],flag[N],son[N][2];
    void pushup(int x){sz[x]=sz[lson]+sz[rson]+sw[x]+v[x];}
    void update(int x){flag[x]^=1;swap(lson,rson);}
    void pushdown(int x)
    {
    	if(!flag[x])return;
    	if(lson)update(lson);
    	if(rson)update(rson);
    	flag[x]=0;
    }
    bool get(int x){return son[f[x]][1]==x;}
    bool isroot(int x){return (son[f[x]][0]!=x)&&(son[f[x]][1]!=x);}
    void rotate(int x)
    {
    	int y=f[x],z=f[y],tx=get(x),ty=get(y),p=son[x][!tx];
    	if(!isroot(y))son[z][ty]=x;son[x][!tx]=y;son[y][tx]=p;
    	if(p)f[p]=y;f[y]=x;f[x]=z;pushup(y);pushup(x);
    }
    void splay(int x)
    {
    	int cnt=0,tmp=x;
    	st[++cnt]=x;
    	while(!isroot(x))st[++cnt]=f[x],x=f[x];
    	for(int i=cnt;i>=1;i--)pushdown(st[i]);
    	x=tmp;
    	while(!isroot(x))
    	{
    		int y=f[x];
    		if(!isroot(y))rotate(get(x)==get(y)?y:x);
    		rotate(x);
    	}
    	pushup(x);
    }
    void access(int x)
    {
    	for(int y=0;x;y=x,x=f[x])
    	{
    		splay(x);
    		sw[x]+=sz[rson];
    		rson=y;
    		sw[x]-=sz[rson];
    		pushup(x);
    	}
    }
    void makeroot(int x){access(x);splay(x);update(x);}
    void link(int x,int y){if(!x||!y)return;makeroot(x);access(y);splay(y);sw[y]+=sz[x];f[x]=y;pushup(y);}
    void cut(int x,int y){if(!x||!y)return;makeroot(x);access(y);splay(y);f[x]=son[y][0]=0;pushup(y);}
    int root=1,last=1,size=1;
    struct node{int len,lnk,nxt[26];}s[N];
    void build(int k)
    {
    	int cur=++size,p=last;
    	last=cur;v[cur]=1;s[cur].len=s[p].len+1;
    	while(p&&!s[p].nxt[k])s[p].nxt[k]=cur,p=s[p].lnk;
    	if(!p){s[cur].lnk=root;link(cur,root);return;}
    	int q=s[p].nxt[k];
    	if(s[q].len==s[p].len+1)s[cur].lnk=q,link(cur,q);
    	else
    	{
    		int clone=++size;
    		s[clone]=s[q];s[clone].len=s[p].len+1;link(clone,s[clone].lnk);
    		while(p&&s[p].nxt[k]==q)s[p].nxt[k]=clone,p=s[p].lnk;
    		cut(q,s[q].lnk);s[q].lnk=s[cur].lnk=clone;link(q,clone);link(cur,clone);
    	}
    }
    int solve(int x)
    {
    	if(!x||x==root)return 0;
    	makeroot(s[x].lnk);access(x);
    	return sw[x]+v[x];
    }
    char t[N*3],opt[20];
    int decode(int k)
    {
    	int len=strlen(t);
    	for(int i=0;i<len;i++)k=(k*131+i)%len,swap(t[i],t[k]);
    	return len;
    }
    int main()
    {
    	int q=read(),len,key=0;
    	scanf("%s",t);len=strlen(t);
    	for(int i=0;i<len;i++)build(t[i]-'A');
    	for(int o=1;o<=q;o++)
    	{
    		scanf("%s",opt);scanf("%s",t);
    		int len=decode(key);
    		if(opt[0]=='Q')
    		{
    			int x=root,flag=false,ans;
    			for(int i=0;i<len;i++)
    			{
    				int k=t[i]-'A';
    				if(!s[x].nxt[k]){flag=true;break;} 
    				x=s[x].nxt[k];
    			}
    			if(flag)ans=0;else ans=solve(x);
    			key^=ans;printf("%d
    ",ans);
    		}
    		else for(int i=0;i<len;i++)build(t[i]-'A');
    	}
    	return 0;
    }
    
  • 相关阅读:
    随机森林算法参数调优
    BAYES和朴素BAYES
    阿里云 金融接口 token PHP
    PHP mysql 按时间分组 表格table 跨度 rowspan
    MySql按周,按月,按日分组统计数据
    PHP 获取今日、昨日、本周、上周、本月的等等常用的起始时间戳和结束时间戳的时间处理类
    thinkphp5 tp5 会话控制 session 登录 退出 检查检验登录 判断是否应该跳转到上次url
    微信 模板消息
    php 腾讯 地图 api 计算 坐标 两点 距离 微信 网页 WebService API
    php添加http头禁止浏览器缓存
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/10354384.html
Copyright © 2011-2022 走看看