2017.9.24 森林 失败总结

来源:互联网 发布:不同表格相同数据查找 编辑:程序博客网 时间:2024/05/18 15:28

这个题就不能链剖了,,必须老老实实用dfs序

dfs序真简单啊、、然而树上路径做多了似乎就只会链剖了

和正常树上距离一样,只不过搬到了主席树上、

然后加边就只要启发式合并即可、注意暴力重构

似乎能link更新的只有倍增lca啊,自己yy的链剖更新太扯没敢写


码:

#include<iostream>#include<cstdio>#include<algorithm>#include<vector>using namespace std;#define N 20000005int ans,siz[N],ch[N][2],last,f[100005][30],a,tot,rt[100005],x,y,top[100005],dui[100005],sz[100005],n,d[100005],fd[100005],laji,m,q,b;char str[99];vector<int>v[100005];void up(int o){siz[o]=siz[ch[o][0]]+siz[ch[o][1]];}void jia(int o,int l,int r,int last){if(l==r){siz[o]=1;return;}int mid=(l+r)>>1;if(a<=mid){if(ch[o][0]==0)ch[o][0]=++tot;ch[o][1]=ch[last][1];jia(ch[o][0],l,mid,ch[last][0]);}else{    if(ch[o][1]==0)ch[o][1]=++tot;ch[o][0]=ch[last][0];jia(ch[o][1],mid+1,r,ch[last][1]);}up(o);}void dfs(int o,int fa,int dis,int tap){top[o]=tap;if(rt[o]==0)rt[o]=++tot;a=dui[o];jia(rt[o],1,n,rt[fa]);d[o]=dis;sz[o]=1;f[o][0]=fa;int i;for(i=1;i<=16;i++)f[o][i]=f[f[o][i-1]][i-1];for(i=0;i<v[o].size();i++){int nd=v[o][i];if(nd==fa)continue;dfs(nd,o,dis+1,tap);sz[o]+=sz[nd];}}struct la{int id,v;}s[100005];bool cmp(la a,la b){return a.v<b.v;}int lca(int x,int y){int i;if(d[x]<d[y])swap(x,y);for(i=16;i>=0;i--){if(d[f[x][i]]>=d[y]){x=f[x][i];}}if(x==y)return x;for(i=16;i>=0;i--){if(f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}}return f[x][0];}void cha(int l,int r,int o1,int o2,int o3,int o4){if(l==r){ans=fd[l];return;}int mid=(l+r)>>1;if(siz[ch[o1][0]]+siz[ch[o2][0]]-siz[ch[o3][0]]-siz[ch[o4][0]]<a){a-=siz[ch[o1][0]]+siz[ch[o2][0]]-siz[ch[o3][0]]-siz[ch[o4][0]];cha(mid+1,r,ch[o1][1],ch[o2][1],ch[o3][1],ch[o4][1]);}else{cha(l,mid,ch[o1][0],ch[o2][0],ch[o3][0],ch[o4][0]);}}int main(){ scanf("%d%d%d%d",&laji,&n,&m,&q);int i;for(i=1;i<=n;i++){scanf("%d",&s[i].v);s[i].id=i;}sort(s+1,s+1+n,cmp);for(i=1;i<=n;i++){dui[s[i].id]=i;fd[i]=s[i].v;}for(i=1;i<=m;i++){scanf("%d%d",&a,&b);v[a].push_back(b);v[b].push_back(a);}for(i=1;i<=n;i++){if(d[i]==0){dfs(i,0,1,i);    }    }while(q--){scanf("%s",str);if(str[0]=='Q'){scanf("%d%d%d",&x,&y,&a);x=x^ans;y=y^ans;a=a^ans;int lin=lca(x,y);cha(1,n,rt[x],rt[y],rt[lin],rt[f[lin][0]]);printf("%d\n",ans);    }else{scanf("%d%d",&x,&y);x^=ans,y^=ans;    if(sz[top[x]]>sz[top[y]])swap(x,y);    v[y].push_back(x);    v[x].push_back(y);dfs(x,y,d[y]+1,top[y]);}}}