BZOJ4771 七彩树

来源:互联网 发布:人工智能语言知乎 编辑:程序博客网 时间:2024/04/29 00:01

很厉害的题

orz了网上的题解,大家似乎都在orz雯舞,那我也赶紧Orz吧,前两天刚在BZOJ把我超了-_-orzorz

然后这题的话,先考虑没有深度的条件

先令每个点的贡献都是1,那么如果有同色点,他们的lca的贡献就要减一,而我们知道取dfs序相邻的两个点的话lca最深,所以令同色点dfs序相邻的点贡献-1,然后答案就是子树和

考虑深度限制,我们对于每一个i,维护只考虑所有深度<=i的点时的答案

考虑现在有深度为i时的答案,那么我们搞个主席树,然后把深度为i+1的点挨个插进来即可,插的时候用set维护一下每个颜色的dfs序,就可以搞了

#include<iostream>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<cstdlib>#include<cstdio>#include<map>#include<bitset>#include<set>#include<stack>#include<vector>#include<queue>using namespace std;#define MAXN 100010#define MAXM 10000010#define ll long long#define eps 1e-8#define MOD 1000000007#define INF 1000000000struct vec{int to;int fro;};struct data{int p;int x;data(){}data(int _p,int _x){p=_p;x=_x;}friend bool operator <(data x,data y){return x.p<y.p;}};vec mp[MAXN];int tai[MAXN],cnt;int n,m;int a[MAXN];int fa[MAXN][20];int dep[MAXN];int siz[MAXN],dfn[MAXN],tim;int p[MAXN];int rt[MAXN];int son[MAXM][2],v[MAXM];int tot;int la;set<data>s[MAXN];bool cmp(int x,int y){return dep[x]<dep[y];}inline void be(int x,int y){mp[++cnt].to=y;mp[cnt].fro=tai[x];tai[x]=cnt;}int lca(int x,int y){int i;if(dep[x]<dep[y]){swap(x,y);}for(i=19;~i;i--){if(dep[fa[x][i]]>=dep[y]){x=fa[x][i];}}for(i=19;~i;i--){if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return x==y?x:fa[x][0];}void dfs(int x){int i,y;dfn[x]=++tim;siz[x]=1;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;dfs(y);siz[x]+=siz[y];}}void change(int &x,int xx,int y,int z,int p,int cv){x=++tot;memcpy(son[x],son[xx],sizeof(son[x]));v[x]=v[xx]+cv;if(y==z){return ;}int mid=y+z>>1;if(p<=mid){change(son[x][0],son[xx][0],y,mid,p,cv);}else{change(son[x][1],son[xx][1],mid+1,z,p,cv);}}int ask(int x,int y,int z,int l,int r){if(!x){return 0;}if(y==l&&z==r){return v[x];}int mid=y+z>>1;if(r<=mid){return ask(son[x][0],y,mid,l,r);}else if(l>mid){return ask(son[x][1],mid+1,z,l,r);}else{return ask(son[x][0],y,mid,l,mid)+ask(son[x][1],mid+1,z,mid+1,r);}}int main(){int i,j,x;int tmp;scanf("%d",&tmp);while(tmp--){memset(fa,0,sizeof(fa));memset(tai,0,sizeof(tai));cnt=0;tim=0;tot=0;la=0;scanf("%d%d",&n,&m);for(i=1;i<=n;i++){scanf("%d",&a[i]);p[i]=i;}dep[1]=1;for(i=2;i<=n;i++){scanf("%d",&x);be(x,i);dep[i]=dep[x]+1;for(j=0;x;j++){fa[i][j]=x;x=fa[x][j];}}dfs(1);int wzh=1;sort(p+1,p+n+1,cmp);for(i=1;i<=n;i++){rt[i]=rt[i-1];while(dep[p[wzh]]==i&&wzh<=n){x=p[wzh];change(rt[i],rt[i],1,n,dfn[x],1);set<data>::iterator it=s[a[x]].insert(data(dfn[x],x)).first;set<data>::iterator itt=it;itt++;if(it!=s[a[x]].begin()&&itt!=s[a[x]].end()){set<data>::iterator tit=it;tit--;change(rt[i],rt[i],1,n,dfn[lca((*tit).x,(*itt).x)],1);}if(it!=s[a[x]].begin()){set<data>::iterator tit=it;tit--;change(rt[i],rt[i],1,n,dfn[lca(x,(*tit).x)],-1);}if(itt!=s[a[x]].end()){change(rt[i],rt[i],1,n,dfn[lca(x,(*itt).x)],-1);}wzh++;}}while(m--){scanf("%d%d",&i,&x);//*i^=la;x^=la;//*/printf("%d\n",la=ask(rt[min(dep[i]+x,n)],1,n,dfn[i],dfn[i]+siz[i]-1));}for(i=1;i<=n;i++){s[i].clear();}}return 0;}/*14 44 2 3 2 1 2 1 3 22 24 14 1*/


0 0