【BZOJ4771】七彩树 主席树+树链的并
生活随笔
收集整理的這篇文章主要介紹了
【BZOJ4771】七彩树 主席树+树链的并
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
【BZOJ4771】七彩樹
Description
給定一棵n個(gè)點(diǎn)的有根樹,編號(hào)依次為1到n,其中1號(hào)點(diǎn)是根節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)都被染上了某一種顏色,其中第i個(gè)節(jié)點(diǎn)的顏色為c[i]。如果c[i]=c[j],那么我們認(rèn)為點(diǎn)i和點(diǎn)j擁有相同的顏色。定義depth[i]為i節(jié)點(diǎn)與根節(jié)點(diǎn)的距離,為了方便起見,你可以認(rèn)為樹上相鄰的兩個(gè)點(diǎn)之間的距離為1。站在這棵色彩斑斕的樹前面,你將面臨m個(gè)問題。每個(gè)問題包含兩個(gè)整數(shù)x和d,表示詢問x子樹里且depth不超過depth[x]+d的所有點(diǎn)中出現(xiàn)了多少種本質(zhì)不同的顏色。請(qǐng)寫一個(gè)程序,快速回答這些詢問。Input
第一行包含一個(gè)正整數(shù)T(1<=T<=500),表示測試數(shù)據(jù)的組數(shù)。 每組數(shù)據(jù)中,第一行包含兩個(gè)正整數(shù)n(1<=n<=100000)和m(1<=m<=100000),表示節(jié)點(diǎn)數(shù)和詢問數(shù)。 第二行包含n個(gè)正整數(shù),其中第i個(gè)數(shù)為c[i](1<=c[i]<=n),分別表示每個(gè)節(jié)點(diǎn)的顏色。 第三行包含n-1個(gè)正整數(shù),其中第i個(gè)數(shù)為f[i+1](1<=f[i]<i),表示節(jié)點(diǎn)i+1的父親節(jié)點(diǎn)的編號(hào)。 接下來m行,每行兩個(gè)整數(shù)x(1<=x<=n)和d(0<=d<n),依次表示每個(gè)詢問。 輸入數(shù)據(jù)經(jīng)過了加密,對(duì)于每個(gè)詢問,如果你讀入了x和d,那么真實(shí)的x和d分別是x xor last和d xor last, 其中l(wèi)ast表示這組數(shù)據(jù)中上一次詢問的答案,如果這是當(dāng)前數(shù)據(jù)的第一組詢問,那么last=0。 輸入數(shù)據(jù)保證n和m的總和不超過500000。Output
對(duì)于每個(gè)詢問輸出一行一個(gè)整數(shù),即答案。Sample Input
15 8
1 3 3 2 2
1 1 3 3
1 0
0 0
3 0
1 3
2 1
2 0
6 2
4 1
Sample Output
12
3
1
1
2
1
1
題解:先不考慮深度的限制。我們分別考慮每種顏色。
如果這個(gè)顏色只有一個(gè)點(diǎn),那么它對(duì)它的所有祖先的貢獻(xiàn)都是1,如果有2個(gè)點(diǎn)a,b,那么它們對(duì)a和b的祖先貢獻(xiàn)都是1,其中兩者lca的祖先被重復(fù)計(jì)算了1次,要將它減去。
以此類推,這些點(diǎn)對(duì)它們的樹鏈的并的貢獻(xiàn)都是1,所以求出樹鏈的并,用線段樹維護(hù)子樹權(quán)值和即可。
但是如果考慮深度限制呢?將線段樹改成主席樹即可,即對(duì)于每個(gè)深度都維護(hù)一棵線段樹。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <set> using namespace std; const int maxn=100010; int n,m,cnt,tot,ans; set<int> S[maxn]; set<int>::iterator it; int to[maxn],next[maxn],head[maxn],fa[19][maxn],dep[maxn],Log[maxn],p[maxn],q[maxn],pd[maxn],Q[maxn],rt[maxn],v[maxn]; struct node {int ls,rs,siz; }s[maxn*50]; void dfs(int x) {p[x]=++q[0],Q[q[0]]=x;for(int i=head[x];i!=-1;i=next[i]) dep[to[i]]=dep[x]+1,dfs(to[i]);q[x]=q[0]; } inline int lca(int a,int b) {if(dep[a]<dep[b]) swap(a,b);for(int i=Log[dep[a]-dep[b]];i>=0;i--) if(dep[fa[i][a]]>=dep[b]) a=fa[i][a];if(a==b) return a;for(int i=Log[dep[a]];i>=0;i--) if(fa[i][a]!=fa[i][b]) a=fa[i][a],b=fa[i][b];return fa[0][a]; } bool cmp(int a,int b) {return dep[a]<dep[b]; } void insert(int x,int &y,int l,int r,int a,int b) {y=++tot,s[y].ls=s[y].rs=s[y].siz=0;s[y].siz=s[x].siz+b;if(l==r) return ;int mid=(l+r)>>1;if(a<=mid) s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,a,b);else s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,a,b); } int query(int l,int r,int x,int a,int b) {if(!x||(a<=l&&r<=b)) return s[x].siz;int mid=(l+r)>>1;if(b<=mid) return query(l,mid,s[x].ls,a,b);if(a>mid) return query(mid+1,r,s[x].rs,a,b);return query(l,mid,s[x].ls,a,b)+query(mid+1,r,s[x].rs,a,b); } inline int rd() {int ret=0,f=1; char gc=getchar();while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();return ret*f; } inline void add(int a,int b) {to[cnt]=b,next[cnt]=head[a],head[a]=cnt++; } void work() {n=rd(),m=rd(),tot=cnt=ans=q[0]=0;int i,j,a,b;memset(head,-1,sizeof(head));memset(rt,0,sizeof(rt));memset(fa,0,sizeof(fa));for(i=1;i<=n;i++) v[i]=rd(),S[i].clear(),pd[i]=i;for(i=2;i<=n;i++) fa[0][i]=rd(),add(fa[0][i],i),Log[i]=Log[i>>1]+1;dep[1]=1,dfs(1);for(j=1;(1<<j)<=n;j++) for(i=1;i<=n;i++) fa[j][i]=fa[j-1][fa[j-1][i]];sort(pd+1,pd+n+1,cmp);for(i=1;i<=n;i++){j=pd[i],a=b=0,it=S[v[j]].lower_bound(p[j]);insert(rt[dep[pd[i-1]]],rt[dep[j]],1,n,p[j],1);if(it!=S[v[j]].end()) b=Q[(*it)],insert(rt[dep[j]],rt[dep[j]],1,n,p[lca(b,j)],-1);if(it!=S[v[j]].begin()) it--,a=Q[(*it)],insert(rt[dep[j]],rt[dep[j]],1,n,p[lca(a,j)],-1);if(a&&b) insert(rt[dep[j]],rt[dep[j]],1,n,p[lca(a,b)],1);S[v[j]].insert(p[j]);}for(i=1;i<=m;i++){a=rd()^ans,b=rd()^ans;ans=query(1,n,rt[min(dep[a]+b,dep[pd[n]])],p[a],q[a]);printf("%d\n",ans);//ans=0;} } int main() {int T=rd();while(T--) work();return 0; }//1 4 4 4 2 3 2 1 2 1 3 2 2 2 4 1 4 1轉(zhuǎn)載于:https://www.cnblogs.com/CQzhangyu/p/7629200.html
總結(jié)
以上是生活随笔為你收集整理的【BZOJ4771】七彩树 主席树+树链的并的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Appium移动自动化配置-ios安卓
- 下一篇: 【9702】黑白棋的移动