[luogu5537]系统设计

考虑哈希,令$h[x]$表示根到$x$路径的哈希值,那么有$h[x]+hash(l,r)=h[ans]$

考虑用线段树维护$a_{i}$的区间哈希值,并用map去找到对应的$ans$

但还有一个问题,就是并不一定都能走完,可以在线段树上二分走到哪里,时间复杂度为$o(nlog^{2}n)$

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 500005
 4 #define L (k<<1)
 5 #define R (L+1)
 6 #define mid (l+r>>1)
 7 #define base 500007
 8 #define mod 998244353
 9 vector<int>v[N];
10 map<int,int>mat;
11 int rt,n,m,q,p,x,y,z,h[N],mi[N],f[N<<2];
12 void update(int k,int l,int r,int x,int y){
13     if (l==r){
14         f[k]=y;
15         return;
16     }
17     if (x<=mid)update(L,l,mid,x,y);
18     else update(R,mid+1,r,x,y);
19     f[k]=(1LL*f[L]*mi[r-mid]+f[R])%mod;
20 }
21 int query(int k,int l,int r,int x,int y){
22     if ((l>y)||(x>r))return 0;
23     if ((x<=l)&&(r<=y))return f[k];
24     int ll=max(mid+1,x),rr=min(r,y),len=max(rr-ll+1,0);
25     return (1LL*query(L,l,mid,x,y)*mi[len]+query(R,mid+1,r,x,y))%mod;
26 }
27 int query(int k,int l,int r,int x,int y,int z){
28     if ((l>y)||(x>r)||(!mat[z]))return 0;
29     if (l==r)return mat[z];
30     int ll=max(l,x),rr=min(mid,y),len=max(rr-ll+1,0);
31     int ans=query(R,mid+1,r,x,y,(1LL*z*mi[len]+query(1,1,n,ll,rr))%mod);
32     if (ans)return ans;
33     return query(L,l,mid,x,y,z);
34 }
35 void dfs(int k,int s){
36     h[k]=s;
37     mat[s]=k;
38     for(int i=0;i<v[k].size();i++)dfs(v[k][i],(1LL*s*base+i+1)%mod);
39 }
40 int main(){
41     mi[0]=1;
42     for(int i=1;i<N-4;i++)mi[i]=1LL*mi[i-1]*base%mod;
43     scanf("%d%d%d",&n,&m,&q);
44     for(int i=1;i<=n;i++){
45         scanf("%d",&x);
46         if (!x)rt=i;
47         else v[x].push_back(i);
48     }
49     dfs(rt,0);
50     for(int i=1;i<=m;i++){
51         scanf("%d",&x);
52         update(1,1,m,i,x);
53     }
54     for(int i=1;i<=q;i++){
55         scanf("%d%d%d",&p,&x,&y);
56         if (p==2)update(1,1,m,x,y);
57         else{
58             scanf("%d",&z);
59             int hh=(1LL*h[x]*mi[z-y+1]+query(1,1,m,y,z))%mod;
60             if (mat[hh])printf("%d
",mat[hh]);
61             else printf("%d
",query(1,1,m,y,z,h[x]));
62         }
63     }
64 } 
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/13957675.html