您的位置:首页 > 其它

【Learning】Link-Cut Tree 题目汇总

2017-12-05 19:44 417 查看
这篇博客主要是记录了我Link-Cut Tree的做题记录。

推荐一个非常好的博客。orz DTZ学长 %%%%%%%

http://www.cnblogs.com/RogerDTZ/p/7436469.html

T1 bzoj2049

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,u,v,fa[10005],ch[10005][2];
char s[20];
bool rev[10005];
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return ch[fa[u]][1]==u;
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
void cut(int u,int v){
makeroot(u);
access(v);
splay(v);
fa[u]=0;
ch[v][0]=0;
}
bool isconnect(int u,int v){
if(u==v){
return true;
}
makeroot(u);
access(v);
splay(v);
return fa[u]!=0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%s%d%d",s,&u,&v);
if(s[0]=='C'){
link(u,v);
}else if(s[0]=='D'){
cut(u,v);
}else{
if(isconnect(u,v)){
puts("Yes");
}else{
puts("No");
}
}
}
return 0;
}


T2 bzoj2002

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=200005;
int n,m,op,x,y,a
,ch
[2],fa
,siz
,rev
;
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
siz[u]=1;
if(ch[u][0]){
siz[u]+=siz[ch[u][0]];
}
if(ch[u][1]){
siz[u]+=siz[ch[u][1]];
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
void cut(int u,int v){
makeroot(u);
access(v);
splay(v);
fa[u]=ch[v][0]=0;
pushup(v);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(i+a[i]<=n){
a[i]=i+a[i];
}else{
a[i]=n+1;
}
link(i,a[i]);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&op,&x);
x++;
if(op==1){
makeroot(n+1);
access(x);
splay(x);
printf("%d\n",siz[ch[x][0]]);
}else{
scanf("%d",&y);
cut(x,a[x]);
if(x+y<=n){
a[x]=x+y;
}else{
a[x]=n+1;
}
link(x,a[x]);
}
}
return 0;
}


T3 bzoj2631

#include<cstdio>
#include<algorithm>
using namespace std;
typedef unsigned int ui;
const int N=100005;
const ui mod=51061;
int n,q,u,v,u2,v2,c,rev
,fa
,ch
[2],siz
;
ui val
,sumv
,mulv
,addv
;
char s[5];
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return ch[fa[u]][1]==u;
}
void pushup(int u){
sumv[u]=val[u];
siz[u]=1;
if(ch[u][0]){
sumv[u]=(sumv[u]+sumv[ch[u][0]])%mod;
siz[u]+=siz[ch[u][0]];
}
if(ch[u][1]){
sumv[u]=(sumv[u]+sumv[ch[u][1]])%mod;
siz[u]+=siz[ch[u][1]];
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void maintain(int u,ui mul,ui add){
addv[u]=(addv[u]*mul%mod+add)%mod;
mulv[u]=mulv[u]*mul%mod;
val[u]=(val[u]*mul%mod+add)%mod;
sumv[u]=(sumv[u]*mul%mod+siz[u]*add%mod)%mod;
}
void downtag(int u){
if(mulv[u]!=1||addv[u]){
if(ch[u][0]){
maintain(ch[u][0],mulv[u],addv[u]);
}
if(ch[u][1]){
maintain(ch[u][1],mulv[u],addv[u]);
}
mulv[u]=1;
addv[u]=0;
}
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
void cut(int u,int v){
makeroot(u);
access(v);
splay(v);
fa[u]=ch[v][0]=0;
pushup(v);
}
main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++){
val[i]=sumv[i]=mulv[i]=1;
}
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
link(u,v);
}
for(int i=1;i<=q;i++){
scanf("%s%d%d",s,&u,&v);
if(s[0]=='+'){
scanf("%d",&c);
makeroot(u);
access(v);
splay(v);
maintain(v,1,c);
}else if(s[0]=='-'){
scanf("%d%d",&u2,&v2);
cut(u,v);
link(u2,v2);
}else if(s[0]=='*'){
scanf("%d",&c);
makeroot(u);
access(v);
splay(v);
maintain(v,c,0);
}else{
makeroot(u);
access(v);
splay(v);
printf("%u\n",sumv[v]);
}
}
return 0;
}


T4 bzoj4530

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
int n,q,u,v,ch
[2],fa
,siz
,sx
,rev
;
char s[10];
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
siz[u]=sx[u]+1;
if(ch[u][0]){
siz[u]+=siz[ch[u][0]];
}
if(ch[u][1]){
siz[u]+=siz[ch[u][1]];
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
sx[u]+=siz[ch[u][1]]-siz[v];
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
makeroot(v);
fa[u]=v;
sx[v]+=siz[u];
pushup(v);
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=q;i++){
scanf("%s%d%d",s,&u,&v);
if(s[0]=='A'){
link(u,v);
}else{
makeroot(u);
access(v);
splay(v);
printf("%lld\n",(long long)(siz[u])*(siz[v]-siz[u]));
}
}
return 0;
}


[b]T5 bzoj2843&&bzoj1180


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=30005;
int n,m,u,v,fa
,val
,siz
,sumv
,rev
,ch
[2];
char s[20];
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
sumv[u]=val[u];
siz[u]=1;
if(ch[u][0]){
sumv[u]+=sumv[ch[u][0]];
siz[u]+=siz[ch[u][0]];
}
if(ch[u][1]){
sumv[u]+=sumv[ch[u][1]];
siz[u]+=siz[ch[u][1]];
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
bool isconnect(int u,int v){
if(u==v){
return true;
}
makeroot(u);
access(v);
splay(v);
return fa[u]!=0;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%s%d%d",s,&u,&v);
if(s[0]=='b'){
if(isconnect(u,v)){
puts("no");
}else{
puts("yes");
link(u,v);
}
}else if(s[0]=='p'){
makeroot(u);
val[u]=v;
pushup(u);
}else{
if(isconnect(u,v)){
makeroot(u);
access(v);
splay(v);
printf("%d\n",sumv[v]);
}else{
puts("impossible");
}
}
}
return 0;
}


T6 hdu4010

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=300005;
int n,q,u,v,w,op,cnt,fa
,ch
[2],val
,rev
,maxv
,tag
;
int uu
,vv
;
void init(){
memset(fa,0,sizeof(fa));
memset(ch,0,sizeof(ch));
memset(val,0,sizeof(val));
memset(rev,0,sizeof(rev));
memset(maxv,0,sizeof(maxv));
memset(tag,0,sizeof(tag));
cnt=0;
}
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
maxv[u]=max(val[u],max(maxv[ch[u][0]],maxv[ch[u][1]]));
}
void reverse(int u){
if(!u){
return;
}
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void maintain(int u,int add){
if(!u){
return;
}
val[u]+=add;
maxv[u]+=add;
tag[u]+=add;
}
void downtag(int u){
if(rev[u]){
reverse(ch[u][0]);
reverse(ch[u][1]);
rev[u]=0;
}
if(tag[u]){
maintain(ch[u][0],tag[u]);
maintain(ch[u][1],tag[u]);
tag[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
if(u==v){
return;
}
makeroot(u);
fa[u]=v;
if(u==v){
exit(0);
}
}
void cut(int u,int v){
if(u==v){
return;
}
makeroot(u);
access(v);
splay(v);
fa[u]=ch[v][0]=0;
pushup(v);
}
bool isconnect(int u,int v){
if(u==v){
return true;
}
makeroot(u);
access(v);
splay(v);
return fa[u]!=0;
}
int main(){
while(~scanf("%d",&n)){
init();
for(int i=1;i<n;i++){
scanf("%d%d",&uu[i],&vv[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
maxv[i]=val[i];
}
for(int i=1;i<n;i++){
link(uu[i],vv[i]);
}
scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d",&u,&v);
if(isconnect(u,v)){
puts("-1");
}else{
link(u,v);
}
}else if(op==2){
scanf("%d%d",&u,&v);
if(!isconnect(u,v)||u==v){
puts("-1");
}else{
cut(u,v);
}
}else if(op==3){
scanf("%d%d%d",&w,&u,&v);
if(!isconnect(u,v)){
puts("-1");
}else{
makeroot(u);
access(v);
splay(v);
maintain(v,w);
}
}else{
scanf("%d%d",&u,&v);
if(!isconnect(u,v)){
puts("-1");
}else{
makeroot(u);
access(v);
splay(v);
printf("%d\n",maxv[v]);
}
}
}
puts("");
}
return 0;
}


T7 bzoj3282

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=300005;
int n,m,op,u,v,fa
,ch
[2],rev
,val
,sumv
;
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
sumv[u]=val[u];
if(ch[u][0]){
sumv[u]^=sumv[ch[u][0]];
}
if(ch[u][1]){
sumv[u]^=sumv[ch[u][1]];
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
void cut(int u,int v){
makeroot(u);
access(v);
splay(v);
fa[u]=ch[v][0]=0;
pushup(v);
}
bool isconnect(int u,int v){
if(u==v){
return true;
}
makeroot(u);
access(v);
splay(v);
return fa[u]!=0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
sumv[i]=val[i];
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&op,&u,&v);
if(op==0){
makeroot(u);
access(v);
splay(v);
printf("%d\n",sumv[v]);
}else if(op==1){
if(!isconnect(u,v)){
link(u,v);
}
}else if(op==2){
if(isconnect(u,v)&&u!=v){
cut(u,v);
}
}else{
makeroot(u);
val[u]=v;
pushup(u);
}
}
return 0;
}


T8 bzoj3669

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=150005,M=150005;
int n,m,ans=0x7f7f7f7f,fa
,ch
[2],rev
;
struct edge{
int u,v,a,b,id;
bool operator < (const edge &a) const{
return b<a.b;
}
}e[M],val
,maxv
;
bool cmp(edge a,edge b){
return a.a<b.a;
}
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
maxv[u]=val[u];
if(ch[u][0]){
maxv[u]=max(maxv[u],maxv[ch[u][0]]);
}
if(ch[u][1]){
maxv[u]=max(maxv[u],maxv[ch[u][1]]);
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
void cut(int u,int v){
makeroot(u);
access(v);
splay(v);
fa[u]=ch[v][0]=0;
pushup(v);
}
bool isconnect(int u,int v){
if(u==v){
return true;
}
makeroot(u);
access(v);
splay(v);
return fa[u]!=0;
}
int main(){
scanf("%d%d",&n,&m);
if(n==1){
puts("0");
return 0;
}
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].a,&e[i].b);
}
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;i++){
e[i].id=i;
val[i+n]=maxv[i+n]=e[i];
}
for(int i=1;i<=m;i++){
if(!isconnect(e[i].u,e[i].v)){
link(e[i].u,i+n);
link(i+n,e[i].v);
}else if(e[i].u!=e[i].v){
makeroot(e[i].u);
access(e[i].v);
splay(e[i].v);
edge tmp=maxv[e[i].v];
if(e[i].b<maxv[e[i].v].b){
cut(tmp.u,tmp.id+n);
cut(tmp.id+n,tmp.v);
link(e[i].u,i+n);
link(i+n,e[i].v);
}
}
if(isconnect(1,n)){
makeroot(1);
access(n);
splay(n);
ans=min(ans,e[i].a+maxv
.b);
}
}
printf("%d\n",ans==0x7f7f7f7f?-1:ans);
return 0;
}


T8 bzoj3306

和遥远的国度一题很像,只不过写了Link-Cut Tree。打了一个Treap。

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=100005;
int n,q,rt,f,x,y,a
,fa
,rev
,minv
,ch
[2];
int siz[N*50],w[N*50],val[N*50],rnd[N*50],c[N*50][2],mmp[N*50];
char s[10];
struct Treap{
int root;
int qmin(){
int k=root;
while(c[k][0]){
k=c[k][0];
}
return val[k];
}
void pushup(int u){
siz[u]=w[u]+siz[c[u][0]]+siz[c[u][1]];
}
void rotate(int &y,int md){
int x=c[y][md];
c[y][md]=c[x][!md];
c[x][!md]=y;
pushup(y);
pushup(x);
y=x;
}
void insert(int &k,int x){
if(!k){
k=mmp[mmp[0]--];
siz[k]=w[k]=1;
c[k][0]=c[k][1]=0;
val[k]=x;
rnd[k]=rand();
return;
}
siz[k]++;
if(x==val[k]){
w[k]++;
}else{
int md=x>val[k];
insert(c[k][md],x);
if(rnd[c[k][md]]<rnd[k]){
rotate(k,md);
}
}
}
void remove(int &k,int x){
siz[k]--;
if(x==val[k]){
if(w[k]>1){
w[k]--;
}else{
if(c[k][0]*c[k][1]==0){
mmp[++mmp[0]]=k;
k=c[k][0]+c[k][1];
}else{
rotate(k,rnd[c[k][0]]>rnd[c[k][1]]);
remove(k,x);
}
}
}else{
remove(c[k][x>val[k]],x);
}
}
}set
;
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
int pushup(int u){
minv[u]=set[u].qmin();
if(ch[u][0]){
minv[u]=min(minv[u],minv[ch[u][0]]);
}
if(ch[u][1]){
minv[u]=min(minv[u],minv[ch[u][1]]);
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[fa[y]][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
if(ch[u][1]){
set[u].insert(set[u].root,minv[ch[u][1]]);
}
ch[u][1]=v;
if(ch[u][1]){
set[u].remove(set[u].root,minv[ch[u][1]]);
}
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
int cnt,head
,to
,nxt
;
void adde(int u,int v){
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
void dfs(int u){
int v;
minv[u]=a[u];
set[u].insert(set[u].root,a[u]);
for(int i=head[u];i;i=nxt[i]){
v=to[i];
dfs(v);
fa[v]=u;
set[u].insert(set[u].root,minv[v]);
}
pushup(u);
}
int main(){
for(int i=5000000;i>=1;i--){
mmp[++mmp[0]]=i;
}
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++){
scanf("%d%d",&f,&a[i]);
if(f){
adde(f,i);
}else{
rt=i;
}
}
dfs(rt);
for(int i=1;i<=q;i++){
scanf("%s%d",s,&x);
if(s[0]=='V'){
scanf("%d",&y);
access(x);
splay(x);
set[x].remove(set[x].root,a[x]);
a[x]=y;
set[x].insert(set[x].root,a[x]);
pushup(x);
}else if(s[0]=='E'){
makeroot(x);
}else{
access(x);
splay(x);
printf("%d\n",set[x].qmin());
}
}
return 0;
}


T9 bzoj2959

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=150005;
int n,m,op,u,v,fu0,fv0,fu1,fv1,pa
[2],fa
,ch
[2],rev
,val
,sumv
;
int a
;
int find(int u,int md){
return u==pa[u][md]?u:pa[u][md]=find(pa[u][md],md);
}
bool isroot(int u){
if(!fa[u]){
return true;
}
int tmp=find(fa[u],1);
return u!=ch[tmp][0]&&u!=ch[tmp][1];
}
int which(int u){
return u==ch[find(fa[u],1)][1];
}
void pushup(int u){
if(!u){
return;
}
sumv[u]=val[u]+sumv[ch[u][0]]+sumv[ch[u][1]];
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
if(!isroot(u)){
pushdown(fa[u]);
}
downtag(u);
}
void rotate(int x){
int y=find(fa[x],1),z=find(fa[y],1),md=x==ch[y][1];
if(y==ch[z][0]||y==ch[z][1]){
ch[z][y==ch[z][1]]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
if(ch[y][md]){
fa[ch[y][md]]=y;
}
ch[x][!md]=y;
if(y){
fa[y]=x;
}
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=find(fa[u],1)){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
int dfs(int rt,int u){
if(!u){
return 0;
}
pa[u][1]=rt;
return dfs(rt,ch[u][0])+dfs(rt,ch[u][1])+val[u];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
pa[i][0]=pa[i][1]=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sumv[i]=val[i]=a[i];
}
for(int i=1;i<=m;i++){
if(i==24){
u++;
}
scanf("%d%d%d",&op,&u,&v);
if(op==1){
if((fu1=find(u,1))!=(fv1=find(v,1))){
if((fu0=find(u,0))!=(fv0=find(v,0))){
makeroot(fu1);
fa[fu1]=fv1;
pa[fv0][0]=fu0;
}else{
makeroot(fu1);
access(fv1);
splay(fv1);
val[fu1]=dfs(fu1,fv1);
fa[fu1]=0;
ch[fu1][0]=ch[fu1][1]=0;
pushup(fu1);
}
}
}else if(op==2){
splay(fu1=find(u,1));
val[fu1]-=a[u];
a[u]=v;
val[fu1]+=a[u];
pushup(fu1);
}else{
if(find(u,0)!=find(v,0)){
puts("-1");
continue;
}
fu1=find(u,1),fv1=find(v,1);
makeroot(fu1);
access(fv1);
splay(fv1);
printf("%d\n",sumv[fv1]);
}
}
return 0;
}


T10 bzoj2594

#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
inline int rd(){
char ch=getchar();
int ret=0,f=1;
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
ret=ret*10+ch-'0';
ch=getchar();
}
return ret*f;
}
const int N=100005,M=1000005;
int n,m,tot,cnt,q,u,v,L
,R
,pa
;
int head[N+M],to[4*N],nxt[4*N];
int fa[N+M],ch[N+M][2],rev[N+M],val[N+M],maxn[N+M],stk[N+M];
int find(int u){
return u==pa[u]?u:pa[u]=find(pa[u]);
}
struct edge{
int u,v,d,id;
bool flag;
}e1[M],e2[M];
struct operation{
int op,u,v,ans;
}op
;
bool cmp1(edge a,edge b){
return a.u==b.u?a.v<b.v:a.u<b.u;
}
bool cmp2(edge a,edge b){
return a.d<b.d;
}
void adde(int u,int v){
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
void dfs(int u){
int v;
for(int i=head[u];i;i=nxt[i]){
v=to[i];
if(v!=fa[u]){
fa[v]=u;
dfs(v);
}
}
}
int find(int u,int v){
int l=L[u],r=R[u],mid;
while(l<=r){
mid=(l+r)/2;
if(e1[mid].v<v){
l=mid+1;
}else if(e1[mid].v>v){
r=mid-1;
}else{
return mid;
}
}
}
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
if(u>n){
maxn[u]=u-n;
}else{
maxn[u]=0;
}
if(e1[maxn[ch[u][0]]].d>e1[maxn[u]].d){
maxn[u]=maxn[ch[u][0]];
}
if(e1[maxn[ch[u][1]]].d>e1[maxn[u]].d){
maxn[u]=maxn[ch[u][1]];
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
}
void pushdown(int u){
stk[stk[0]=1]=u;
for(;!isroot(u);u=fa[u]){
stk[++stk[0]]=fa[u];
}
while(stk[0]){
downtag(stk[stk[0]--]);
}
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
void cut(int u,int v){
makeroot(u);
access(v);
splay(v);
fa[u]=ch[v][0]=0;
pushup(v);
}
int main(){
n=rd(),m=rd(),q=rd();
for(int i=1;i<=m;i++){
e1[i].u=rd(),e1[i].v=rd(),e1[i].d=rd();
if(e1[i].u>e1[i].v){
e1[i].u^=e1[i].v;
e1[i].v^=e1[i].u;
e1[i].u^=e1[i].v;
}
}
sort(e1+1,e1+m+1,cmp1);
for(int i=1;i<=m;i++){
e1[i].id=i;
maxn[i+n]=i;
}
L[1]=1;
R
=m;
for(int i=2;i<=m;i++){
if(e1[i].u!=e1[i-1].u){
L[e1[i].u]=i;
R[e1[i-1].u]=i-1;
}
}
for(int i=1;i<=q;i++){
op[i].op=rd(),op[i].u=rd(),op[i].v=rd();
if(op[i].op==2){
if(op[i].u>op[i].v){
op[i].u^=op[i].v;
op[i].v^=op[i].u;
op[i].u^=op[i].v;
}
u=find(op[i].u,op[i].v);
e1[u].flag=true;
}
}
for(int i=1;i<=m;i++){
if(!e1[i].flag){
e2[++tot]=e1[i];
}
}
sort(e2+1,e2+tot+1,cmp2);
for(int i=1;i<=n;i++){
pa[i]=i;
}
for(int i=1,j=0;i<=tot&&j!=n-1;i++){
u=find(e2[i].u),v=find(e2[i].v);
if(u!=v){
j++;
pa[v]=u;
adde(e2[i].u,e2[i].id+n);
adde(e2[i].id+n,e2[i].u);
adde(e2[i].v,e2[i].id+n);
adde(e2[i].id+n,e2[i].v);
}
}
dfs(1);
for(int i=q;i>=1;i--){
if(op[i].op==1){
makeroot(op[i].u);
access(op[i].v);
splay(op[i].v);
op[i].ans=e1[maxn[op[i].v]].d;
}else{
makeroot(op[i].u);
access(op[i].v);
splay(op[i].v);
u=maxn[op[i].v],v=find(op[i].u,op[i].v);
if(e1[u].d>e1[v].d){
cut(e1[u].u,u+n);
cut(u+n,e1[u].v);
link(e1[v].u,v+n);
link(v+n,e1[v].v);
}
}
}
for(int i=1;i<=q;i++){
if(op[i].op==1){
printf("%d\n",op[i].ans);
}
}
return 0;
}


T11 uva11994

各种乱搞之后终于过了!仍然把边变成点。

其实我的代码判断祖孙关系非常暴力,可以被卡。暂时没想到怎么在动态树中快速判断祖孙关系==

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=50005;
int n,m,op,u,v,c,cnt,ans,pa
,rt
;
int fa[N*2],ch[N*2][2],rev[N*2],tag[N*2],sumv[N*2],siz[N*2],val[N*2],stk[N*2];
int head[N*2],to[N*4],nxt[N*4];
void adde(int u,int v){
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
void dfs(int u){
int v;
for(int i=head[u];i;i=nxt[i]){
v=to[i];
if(v!=fa[u]){
fa[v]=u;
dfs(v);
}
}
}
bool isroot(int u){
return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
int which(int u){
return u==ch[fa[u]][1];
}
void pushup(int u){
sumv[u]=1<<val[u];
siz[u]=1;
if(ch[u][0]){
sumv[u]|=sumv[ch[u][0]];
siz[u]+=siz[ch[u][0]];
}
if(ch[u][1]){
sumv[u]|=sumv[ch[u][1]];
siz[u]+=siz[ch[u][1]];
}
}
void reverse(int u){
rev[u]^=1;
swap(ch[u][0],ch[u][1]);
}
void maintain(int u,int c){
tag[u]=c;
sumv[u]=1<<c;
if(u>n){
val[u]=c;
}
}
void downtag(int u){
if(rev[u]){
if(ch[u][0]){
reverse(ch[u][0]);
}
if(ch[u][1]){
reverse(ch[u][1]);
}
rev[u]=0;
}
if(tag[u]){
if(ch[u][0]){
maintain(ch[u][0],tag[u]);
}
if(ch[u][1]){
maintain(ch[u][1],tag[u]);
}
tag[u]=0;
}
}
void pushdown(int u){
stk[stk[0]=1]=u;
for(;!isroot(u);u=fa[u]){
stk[++stk[0]]=fa[u];
}
while(stk[0]){
downtag(stk[stk[0]--]);
}
}
void rotate(int x){
int y=fa[x],z=fa[y],md=which(x);
if(!isroot(y)){
ch[z][which(y)]=x;
}
fa[x]=z;
ch[y][md]=ch[x][!md];
fa[ch[y][md]]=y;
ch[x][!md]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void splay(int u){
pushdown(u);
while(!isroot(u)){
if(!isroot(fa[u])){
rotate(which(fa[u])==which(u)?fa[u]:u);
}
rotate(u);
}
}
void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
ch[u][1]=v;
pushup(u);
}
}
void makeroot(int u){
access(u);
splay(u);
reverse(u);
}
void link(int u,int v){
makeroot(u);
fa[u]=v;
}
void cut(int u,int v){
makeroot(u);
access(v);
splay(v);
fa[u]=ch[v][0]=0;
pushup(v);
}
bool judge(int u,int v){
while(v){
if(u==v){
return false;
}
v=pa[v];
}
return true;
}
bool isconnect(int u,int v){
if(u==v){
return true;
}
makeroot(u);
access(v);
splay(v);
return fa[u]!=0;
}
int main(){
while(~scanf("%d%d",&n,&m)){
memset(fa,0,sizeof(fa));
memset(ch,0,sizeof(ch));
memset(rev,0,sizeof(rev));
memset(tag,0,sizeof(tag));
memset(sumv,0,sizeof(sumv));
memset(siz,0,sizeof(siz));
memset(val,0,sizeof(val));
memset(head,0,sizeof(head));
rt[0]=cnt=0;
for(int i=1;i<=n;i++){
scanf("%d",&pa[i]);
if(pa[i]){
adde(pa[i],i+n);
adde(i+n,pa[i]);
adde(i,i+n);
adde(i+n,i);
}else{
rt[++rt[0]]=i;
}
}
for(int i=1;i<=n;i++){
scanf("%d",&val[i+n]);
sumv[i+n]=1<<val[i+n];
siz[i]=siz[i+n]=1;
}
for(int i=1;i<=rt[0];i++){
dfs(rt[i]);
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&op,&u,&v);
if(op==1){
scanf("%d",&c);
if(judge(u,v)){
if(pa[u]){
cut(pa[u],u+n);
cut(u+n,u);
}
pa[u]=v;
link(pa[u],u+n);
link(u+n,u);
splay(u+n);
val[u+n]=c;
pushup(u+n);
}
}else if(op==2){
scanf("%d",&c);
if(u!=v&&isconnect(u,v)){
makeroot(u);
access(v);
splay(v);
maintain(v,c);
}
}else{
if(u==v||!isconnect(u,v)){
puts("0 0");
}else{
makeroot(u);
access(v);
splay(v);
ans=0;
for(int j=1;j<=30;j++){
if(sumv[v]&(1<<j)){
ans++;
}
}
printf("%d %d\n",(siz[v]-1)/2,ans);
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: