样例都没过。。。。但已经怼着看了两天了。。。。求救巨佬。。。!!
完整代码在最下面,输出是
3
2
-3
-2
1
3
所以我觉得可能是N操作(取反)有问题。
这里是关于N操作的所有代码块:
void Change(int x,int y)
{
if(x==y)
return ;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
LineChange(tid[top[x]],tid[x],1);
x=prt[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
LineChange(tid[x]+1,tid[y],1);
return ;
}
void LineChange(int l,int r,int k) //线段树上的
{
if((l>Tree[k].r) || (r<Tree[k].l))
return ;
if((l>=Tree[k].l) && (r<=Tree[k].r))
{
Lazy(k);
return ;
}
PushDown(k);
int mid=(l+r)>>1;
if(l<=mid)
LineChange(l,r,2*k);
if(mid<r)
LineChange(l,r,2*k+1);
PushUp(k);
}
void Lazy(int k) //懒标记
{
Tree[k].num*=-1;
swap(Tree[k].ma,Tree[k].mi);
Tree[k].ma*=-1;
Tree[k].mi*=-1;
Tree[k].flag=!Tree[k].flag;
}
下面是完整代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=20010;
const int inf=1<<28;
int n;
struct Edge
{
int to,next,w;
}a[maxn<<1];
int head[maxn],cnt;
void AddEdge(int x,int y,int w)
{
a[++cnt].next=head[x];
a[cnt].to=y;
a[cnt].w=w;
head[x]=cnt;
}
struct Init
{
int x,y;
}Q[maxn];
struct Node
{
int r,l;
int num;
int mi,ma;
int flag;
}Tree[maxn<<2];
int size[maxn];
int son[maxn];
int prt[maxn];
int dep[maxn];
int va[maxn];
void DFS_1(int x,int fa,int d)
{
size[x]=1;
prt[x]=fa;
dep[x]=d;
for(int i=head[x];i;i=a[i].next)
{
int y=a[i].to;
if(y!=fa)
{
va[y]=a[i].w;
DFS_1(y,x,d+1);
size[x]+=size[y];
if((!son[x]) || (size[y]>size[son[x]]))
son[x]=y;
}
}
}
int top[maxn];
int tid[maxn];
int rank[maxn];
int flag;
void DFS_2(int x,int t)
{
top[x]=t;
tid[x]=++flag;
rank[tid[x]]=va[x];
if(son[x])
DFS_2(son[x],t);
for(int i=head[x];i;i=a[i].next)
{
int y=a[i].to;
if((y!=son[x]) && (y!=prt[x]))
DFS_2(y,y);
}
}
void PushUpMax(int x)
{
int xr=Tree[2*x].ma;
int xl=Tree[2*x+1].ma;
Tree[x].ma=max(xr,xl);
}
void PushUpMin(int x)
{
int xr=Tree[2*x].mi;
int xl=Tree[2*x+1].mi;
Tree[x].mi=min(xr,xl);
}
void PushUpSum(int x)
{
int xr=Tree[2*x].num;
int xl=Tree[2*x+1].num;
Tree[x].num=xr+xl;
}
void PushUp(int k)
{
PushUpMax(k);
PushUpMin(k);
PushUpSum(k);
}
void Lazy(int k)
{
Tree[k].num*=-1;
swap(Tree[k].ma,Tree[k].mi);
Tree[k].ma*=-1;
Tree[k].mi*=-1;
Tree[k].flag=!Tree[k].flag;
}
void PushDown(int k)
{
if(!Tree[k].flag)
return ;
int l=2*k;
int r=2*k+1;
Lazy(l);
Lazy(r);
Tree[k].flag=0;
}
void Inser(int x,int d,int k)
{
if((d<Tree[k].l) || (d>Tree[k].r))
return ;
if(Tree[k].l==Tree[k].r)
{
Tree[k].num=Tree[k].ma=Tree[k].mi=x;
return ;
}
int mid=(Tree[k].l+Tree[k].r)>>1;
PushDown(k);
if(d>mid)
Inser(x,d,2*k+1);
else Inser(x,d,2*k);
PushUp(k);
}
void LineChange(int l,int r,int k)
{
if((l>Tree[k].r) || (r<Tree[k].l))
return ;
if((l>=Tree[k].l) && (r<=Tree[k].r))
{
Lazy(k);
return ;
}
PushDown(k);
int mid=(l+r)>>1;
if(l<=mid)
LineChange(l,r,2*k);
if(mid<r)
LineChange(l,r,2*k+1);
PushUp(k);
}
void Change(int x,int y)
{
if(x==y)
return ;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
LineChange(tid[top[x]],tid[x],1);
x=prt[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
LineChange(tid[x]+1,tid[y],1);
return ;
}
int LineMax(int l,int r,int k)
{
if((l>Tree[k].r) || (r<Tree[k].l))
return -inf;
if((l>=Tree[k].l) && (r<=Tree[k].r))
return Tree[k].ma;
PushDown(k);
int ans=-inf;
int mid=(l+r)>>1;
if(l<=mid)
ans=max(LineMax(l,r,2*k),ans);
if(mid<r)
ans=max(ans,LineMax(l,r,2*k+1));
return ans;
}
int LineMin(int l,int r,int k)
{
if((l>Tree[k].r) || (r<Tree[k].l))
return inf;
if((l>=Tree[k].l) && (r<=Tree[k].r))
return Tree[k].mi;
PushDown(k);
int ans=inf;
int mid=(l+r)>>1;
if(l<=mid)
ans=min(LineMin(l,r,2*k),ans);
if(mid<r)
ans=min(ans,LineMin(l,r,2*k+1));
return ans;
}
int AskMax(int x,int y)
{
if(x==y)
return -1;
int ans=-inf;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
ans=max(LineMax(tid[top[x]],tid[x],1),ans);
x=prt[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
ans=max(LineMax(tid[x]+1,tid[y],1),ans);
return ans;
}
int AskMin(int x,int y)
{
if(x==y)
return -1;
int ans=inf;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
ans=min(LineMin(tid[top[x]],tid[x],1),ans);
x=prt[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
ans=min(LineMin(tid[x]+1,tid[y],1),ans);
return ans;
}
int LineSum(int l,int r,int k)
{
if((l>Tree[k].r) || (r<Tree[k].l))
return 0;
if((l>=Tree[k].l) && (r<=Tree[k].r))
return Tree[k].num;
PushDown(k);
int ans=0;
int mid=(l+r)>>1;
if(l<=mid)
ans+=LineSum(l,r,2*k);
if(mid<r)
ans+=LineSum(l,r,2*k+1);
return ans;
}
int AskSum(int x,int y)
{
if(x==y)
return -1;
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
ans+=LineSum(tid[top[x]],tid[x],1);
x=prt[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
ans+=LineSum(tid[x]+1,tid[y],1);
return ans;
}
void BuildTree(int l,int r,int k)
{
Tree[k].l=l;
Tree[k].r=r;
Tree[k].ma=Tree[k].mi=0;
Tree[k].num=0;
if(r==l)
{
Tree[k].ma=Tree[k].mi=Tree[k].num=rank[l];
return ;
}
int mid=(l+r)>>1;
BuildTree(l,mid,2*k);
BuildTree(mid+1,r,2*k+1);
PushUp(k);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
Q[i].x=x+1;
Q[i].y=y+1;
AddEdge(x+1,y+1,w);
AddEdge(y+1,x+1,w);
}
DFS_1(1,1,1);
DFS_2(1,1);
BuildTree(1,n,1);
int m;
scanf("%d",&m);
while(m--)
{
string op;
cin>>op;
if(op=="C")
{
int i,w;
scanf("%d%d",&i,&w);
if(prt[Q[i].y]==Q[i].x)
swap(Q[i].x,Q[i].y);
Inser(w,tid[Q[i].x],1);
}
if(op=="N")
{
int u;
int v;
scanf("%d%d",&u,&v);
Change(u+1,v+1);
}
if(op=="MAX")
{
int u,v;
scanf("%d%d",&u,&v);
int ans=AskMax(u+1,v+1);
printf("%d\n",ans);
}
if(op=="MIN")
{
int u,v;
scanf("%d%d",&u,&v);
int ans=AskMin(u+1,v+1);
printf("%d\n",ans);
}
if(op=="SUM")
{
int u,v;
scanf("%d%d",&u,&v);
int ans=AskSum(u+1,v+1);
printf("%d\n",ans);
}
}
return 0;
}
谢谢巨佬们。。。!!CCCCCCCCCCCCOrz