一个挺简单的一个动态树,结果多写了一个标记,导致代码量大幅度增加,再加上一个脑残错误...
本来以为多updata几次至少不会错,结果在一个地方updata之前还存有标记...
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
const int oo=1073741819;
using namespace std;
struct PP{
int p,k;
};
int n,m,ss;
int tail[500000],next[1000000],sora[1000000];
int l[500000],r[500000],rt[500000];
int sw[500000],t[500000][2],Max[500000][2],sum[500000][2],w[500000],size[500000];
void modify_add(int x,int p)
{
if (!x) return ;
if (t[x][0]>-oo) {
t[x][0]+=p,t[x][1]=-oo;
if (Max[x][0]>-oo) Max[x][0]+=p;
if (Max[x][1]>-oo) Max[x][1]+=p;
w[x]+=p;
return ;
}
t[x][0]=-oo;
if (t[x][1]>-oo) t[x][1]+=p;
else t[x][1]=p;
if (Max[x][0]>-oo) Max[x][0]+=p;
if (Max[x][1]>-oo) Max[x][1]+=p;
w[x]+=p;
}
void modify_fuzhi(int x,int p)
{
if (!x) return ;
t[x][0]=p,t[x][1]=-oo;
Max[x][0]=p,sum[x][0]=size[x];
Max[x][1]=-oo,sum[x][1]=0;
w[x]=p;
}
void swap(int x)
{
if (!x) return ;
swap(l[x],r[x]);
sw[x]^=1;
}
void merge(PP A[],int P,int K)
{
for (int i=0;i<=1;i++)
if (A[i].p==P) {
A[i].k+=K;
return ;
}
if (P>A[0].p) {
A[1]=A[0];
A[0].p=P,A[0].k=K;
}
else if (P>A[1].p) {
A[1].p=P,A[1].k=K;
}
}
void updata(int x)
{
if (!x) return ;
//if (sw[x] || t[x][0]>-oo || t[x][1]>-oo) return ;
PP ans[2];
ans[0].p=ans[1].p=-oo;
ans[0].k=ans[1].k=0;
merge(ans,w[x],1);
for (int i=0;i<=1;i++) {
if (l[x]) merge(ans,Max[l[x]][i],sum[l[x]][i]);
if (r[x]) merge(ans,Max[r[x]][i],sum[r[x]][i]);
}
Max[x][0]=ans[0].p,sum[x][0]=ans[0].k;
Max[x][1]=ans[1].p,sum[x][1]=ans[1].k;
size[x]=size[l[x]]+size[r[x]]+1;
}
void pushdown(int x)
{
if (!x) return ;
if (sw[x]) {
swap(l[x]),swap(r[x]);
sw[x]=0;
}
if (t[x][0]>-oo) {
modify_fuzhi(l[x],t[x][0]);
modify_fuzhi(r[x],t[x][0]);
t[x][0]=-oo;
}
if (t[x][1]>-oo) {
modify_add(l[x],t[x][1]);
modify_add(r[x],t[x][1]);
t[x][1]=-oo;
}
updata(x);
}
void right(int x)
{
int y=rt[x],z=rt[y];
l[y]=r[x],rt[r[x]]=y;
r[x]=y,rt[y]=x;
if (l[z]==y) l[z]=x;else if (r[z]==y) r[z]=x;
rt[x]=z;
updata(y);
}
void left(int x)
{
int y=rt[x],z=rt[y];
r[y]=l[x],rt[l[x]]=y;
l[x]=y,rt[y]=x;
if (l[z]==y) l[z]=x;else if (r[z]==y) r[z]=x;
rt[x]=z;
updata(y);
}
void splay(int x)
{
pushdown(x);
for (int y,z;l[rt[x]]==x || r[rt[x]]==x;) {
y=rt[x],z=rt[y];
if (l[z]==y || r[z]==y) pushdown(z);
pushdown(y),pushdown(x);
if (l[y]==x) {
if (l[z]==y) right(y);
right(x);
}
else if (r[y]==x) {
if (r[z]==y) left(y);
left(x);
}
}
updata(x);
}
void access(int x)
{
splay(x);
l[x]=0,updata(x);
for (;rt[x];) {
int y=rt[x];
splay(y);
l[y]=x,updata(y);
splay(x);
}
}
void origin()
{
ss=n;
for (int i=1;i<=n;i++) tail[i]=i,next[i]=0;
for (int i=1;i<=n;i++) {
sw[i]=0;
t[i][0]=t[i][1]=-oo;
Max[i][0]=Max[i][1]=-oo;
sum[i][0]=sum[i][1]=0,rt[i]=0;
Max[i][0]=w[i];
sum[i][0]=1;
size[i]=1;
l[i]=r[i]=0;
}
}
void link(int x,int y)
{
++ss,next[tail[x]]=ss,tail[x]=ss,sora[ss]=y,next[ss]=0;
++ss,next[tail[y]]=ss,tail[y]=ss,sora[ss]=x,next[ss]=0;
}
void dfs(int x,int y)
{
for (int i=x,ne;next[i];) {
i=next[i],ne=sora[i];
if (ne!=y) rt[ne]=x,dfs(ne,x);
}
}
int ask(int x,int y)
{
access(x),access(y);
splay(x);
if (rt[x]) return rt[x];
return x;
}
void Del(int x,int y)
{
int lca=ask(x,y);
if (lca==x) swap(x,y);
access(y);
splay(x),splay(y);
rt[x]=0;
updata(x),updata(y); //updata前标记没有下放
}
void Link(int x,int y)
{
access(x);
splay(x),splay(y);
swap(x);
rt[x]=y;
updata(x),updata(y); //updata前标记没有下放
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int T;
scanf("%d",&T);
for (int test=1;T;T--,test++) {
printf("Case #%d:\n",test);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&w[i]);
origin();
for (int i=1;i<=n-1;i++) {
int x,y;
scanf("%d%d",&x,&y);
link(x,y);
}
dfs(1,0);
for (int i=1;i<=m;i++) {
int c;
scanf("%d",&c);
if (1==c) {
int x,y,a,b;
scanf("%d%d%d%d",&x,&y,&a,&b);
if (x!=y) Del(x,y);
if (a!=b) Link(a,b);
}
else if (2==c) {
int a,b,x;
scanf("%d%d%d",&a,&b,&x);
if (a==b) {
splay(a);
pushdown(a);
w[a]=x;
updata(a);
continue;
}
int lca=ask(a,b);
if (lca==a) swap(a,b);
if (lca==b) {
access(a),access(b);
splay(a);
modify_fuzhi(a,x);
splay(b);
pushdown(b);
w[b]=x;
updata(b);
}
else {
access(a),access(b),access(lca);
splay(a),modify_fuzhi(a,x);
splay(b),modify_fuzhi(b,x);
splay(lca);
pushdown(lca);
w[lca]=x;
updata(lca);
}
}
else if (3==c) {
int a,b,x;
scanf("%d%d%d",&a,&b,&x);
if (a==b) {
splay(a);
pushdown(a);
w[a]+=x;
updata(a);
continue;
}
int lca=ask(a,b);
if (lca==a) swap(a,b);
if (lca==b) {
access(a),access(b);
splay(a);
modify_add(a,x);
splay(b);
pushdown(b);
w[b]+=x;
updata(b);
}
else {
access(a),access(b),access(lca);
splay(a),modify_add(a,x);
splay(b),modify_add(b,x);
splay(lca);
pushdown(lca);
w[lca]+=x;
updata(lca);
}
}
else if (4==c) {
int a,b;
scanf("%d%d",&a,&b);
if (a==b) {
printf("ALL SAME\n");
continue;
}
PP ans[2];
ans[0].p=ans[1].p=-oo;
ans[0].k=ans[1].k=0;
int lca=ask(a,b);
if (lca==a) swap(a,b);
if (lca==b) {
access(a),access(b);
splay(a);
merge(ans,Max[a][0],sum[a][0]);
merge(ans,Max[a][1],sum[a][1]);
splay(b);
merge(ans,w[b],1);
}
else {
access(a),access(b),access(lca);
splay(a),splay(b);
merge(ans,Max[a][0],sum[a][0]),merge(ans,Max[a][1],sum[a][1]);
merge(ans,Max[b][0],sum[b][0]),merge(ans,Max[b][1],sum[b][1]);
splay(lca);
merge(ans,w[lca],1);
}
if (!ans[1].k) printf("ALL SAME\n");
else printf("%d %d\n",ans[1].p,ans[1].k);
}
}
}
return 0;
}