[LuoguU41039]PION後綴自動機 樹鏈剖分
阿新 • • 發佈:2018-10-23
def names tor org cto else sign del class
鏈接
剛開始看出題人題解都嚇蒙掉了,還以為是什麽難題,結果就一板子題
思路:對每一個文件名開一棵線段樹,然後樹剖即可
#include<bits/stdc++.h> #define REP(i,a,b) for(int i(a);i<=(b);++i) #define dbg(...) fprintf(stderr,__VA_ARGS__) using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef pair<int,int>pii; template<typename T,typename U>inline char smin(T&x,const U&y){return x>y?x=y,1:0;} template<typename T,typename U>inline char smax(T&x,const U&y){return x<y?x=y,1:0;} int T; struct hash_table{ static const int S=1e6+5; int head[S],to[S],ne[S]; inline int get(char *s){ int u=0;while(*s)u=u*27+*s++-‘a‘+1;int p=u%S; for(int i=head[p];i;i=ne[i])if(to[i]==u)return i; to[++T]=u,ne[T]=head[p],head[p]=T; return T; } }mp; const int N=1e5+5,MT=5e5+5; int n,m; vector<int>g[N]; int fa[N],dep[N],top[N],in[N],son[N],siz[N],dfn; inline void go1(int x){ siz[x]=1; for(int y:g[x])if(y!=fa[x]) dep[y]=dep[x]+1,fa[y]=x,go1(y),siz[x]+=siz[y],siz[y]>siz[son[x]]&&(son[x]=y); } inline void go2(int x,int anc){ in[x]=++dfn,top[x]=anc; if(!son[x])return;go2(son[x],anc); for(int y:g[x])if(y!=fa[x]&&y!=son[x])go2(y,y); } inline int dis(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans+=dep[x]-dep[top[x]]+1;x=fa[top[x]]; } return ans+abs(dep[x]-dep[y]); } int rt[MT],treecnt; struct tree{int ls,rs,w;bool del;}t[MT*25]; inline void ins(int&o,int l,int r,int x){ if(!o)o=++treecnt;++t[o].w; if(l==r)return;int mid=l+r>>1; x<=mid?ins(t[o].ls,l,mid,x):ins(t[o].rs,mid+1,r,x); } inline void pushdown(int o){ if(t[o].del){ if(t[o].ls)t[t[o].ls].w=0,t[t[o].ls].del=1; if(t[o].rs)t[t[o].rs].w=0,t[t[o].rs].del=1; t[o].del=0; } } inline int ask(int o,int l,int r,int x,int y){ if(!o||x>r||y<l||x>y||t[o].del)return 0; if(x<=l&&r<=y)return t[o].w;pushdown(o); int mid=l+r>>1; return ask(t[o].ls,l,mid,x,y)+ask(t[o].rs,mid+1,r,x,y); } inline int update(int o,int l,int r,int x,int y){ if(!o||x>y||t[o].del)return 0; if(x<=l&&r<=y){ int res=t[o].w;t[o].w=0;t[o].del=1;return res; } int mid=l+r>>1,res=0;pushdown(o); if(x<=mid)res+=update(t[o].ls,l,mid,x,y); if(y>mid)res+=update(t[o].rs,mid+1,r,x,y); t[o].w=t[t[o].ls].w+t[t[o].rs].w; return res; } inline int ask(int o,int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans+=ask(o,1,n,in[top[x]],in[x]);x=fa[top[x]]; } if(dep[x]>dep[y])swap(x,y); return ans+ask(o,1,n,in[x],in[y]); } inline int update(int o,int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans+=update(o,1,n,in[top[x]],in[x]);x=fa[top[x]]; } if(dep[x]>dep[y])swap(x,y); return ans+update(o,1,n,in[x],in[y]); } int main(){ scanf("%d%d",&n,&m); REP(i,2,n){ #define pb push_back int x,y;scanf("%d%d",&x,&y);g[x].pb(y),g[y].pb(x); } go1(1),go2(1,1); static char s[10]; REP(i,1,n){ int t;scanf("%d",&t); while(t--){ scanf("%s",s); ins(rt[mp.get(s)],1,n,in[i]); } } while(m--){ scanf("%s",s); int x,y; if(s[0]==‘q‘){ scanf("%s%d%d",s,&x,&y); if(s[1]==‘p‘)printf("%d\n",dis(x,y)); else{ scanf(" *.%s",s);printf("%d\n",ask(rt[mp.get(s)],x,y)); } }else{ scanf("%*s%d%d *.%s",&x,&y,s); printf("%d\n",update(rt[mp.get(s)],x,y)); } } return 0; }
[LuoguU41039]PION後綴自動機 樹鏈剖分