poj3237 Tree

来源:互联网 发布:paxos算法 应用 编辑:程序博客网 时间:2024/05/01 12:20

题目链接:...G20过了再补

题目大意:

三种操作:
CHANGE i v:改变第i条边的值
NEGATE a b:将a到b路径上的边取绝对值
QUERY a b:询问a到b路径上边的最大值


题解:当,,,就树剖..(LCT线段树也可以貌似

调了很久还能说什么orz更新什么的要及时

p.s.范围开大TLE开小RE。。

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define maxn 20100#define INF 0x7fffffffstruct node{int x,y,c,next;}a[maxn*2],e[maxn];int len,first[maxn];struct tree{int l,r,lc,rc,rev,mxx,mnn;}tr[maxn];int trlen;int mymax(int x,int y){return (x>y)?x:y;}int mymin(int x,int y){return (x<y)?x:y;}void ins(int x,int y){len++;//a[len].c=c;a[len].x=x;a[len].y=y;a[len].next=first[x];first[x]=len;}int son[maxn],fa[maxn],dep[maxn];int z,tot[maxn],top[maxn],ys[maxn];void dfs1(int x){tot[x]=1;son[x]=0;for (int k=first[x];k!=-1;k=a[k].next){int y=a[k].y;if (y!=fa[x]){dep[y]=dep[x]+1;fa[y]=x;dfs1(y);if (tot[son[x]]<tot[y]) son[x]=y;tot[x]+=tot[y];}}}void dfs2(int x,int tp){ys[x]=++z;top[x]=tp;if (son[x]!=0) dfs2(son[x],tp);for (int k=first[x];k!=-1;k=a[k].next){int y=a[k].y;if (y!=fa[x] && y!=son[x]) dfs2(y,y);}}void bt(int l,int r){trlen++;int now=trlen;tr[now].l=l;tr[now].r=r;tr[now].lc=tr[now].rc=-1;tr[now].rev=0;tr[now].mnn=INF;tr[now].mxx=-INF;if (l<r){int mid=(l+r)>>1;tr[now].lc=trlen+1;bt(l,mid);tr[now].rc=trlen+1;bt(mid+1,r);}}void swop(int &x,int &y){int tt=x;x=y;y=tt;}void updata(int now,int lc,int rc){if (tr[now].rev){if (lc!=0){swop(tr[lc].mxx,tr[lc].mnn);tr[lc].mxx=-tr[lc].mxx;tr[lc].mnn=-tr[lc].mnn;tr[lc].rev^=1;}if (rc!=0){swop(tr[rc].mxx,tr[rc].mnn);tr[rc].mxx=-tr[rc].mxx;tr[rc].mnn=-tr[rc].mnn;tr[rc].rev^=1;}tr[now].rev=0;}}void change(int now,int x,int k){if (tr[now].l==tr[now].r) {tr[now].mxx=tr[now].mnn=k;tr[now].rev=0;return;}int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)>>1;updata(now,lc,rc);if (x<=mid) change(lc,x,k);else change(rc,x,k);tr[now].mxx=mymax(tr[lc].mxx,tr[rc].mxx);tr[now].mnn=mymin(tr[lc].mnn,tr[rc].mnn);}int findmx(int now,int l,int r){if (tr[now].l==l && tr[now].r==r) return tr[now].mxx;int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)>>1;updata(now,lc,rc);if (r<=mid) return findmx(lc,l,r);else if (l>mid) return findmx(rc,l,r);else return mymax(findmx(lc,l,mid),findmx(rc,mid+1,r));}void fanz(int now,int l,int r){if (tr[now].l==l && tr[now].r==r){swop(tr[now].mxx,tr[now].mnn);tr[now].mxx=-tr[now].mxx;tr[now].mnn=-tr[now].mnn;tr[now].rev^=1;return;}int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)>>1;updata(now,lc,rc);if (r<=mid) fanz(lc,l,r);else if (l>mid) fanz(rc,l,r);else fanz(lc,l,mid),fanz(rc,mid+1,r);tr[now].mxx=mymax(tr[lc].mxx,tr[rc].mxx);tr[now].mnn=mymin(tr[lc].mnn,tr[rc].mnn);}int query(int x,int y){int tx=top[x],ty=top[y],ans=-INF;while (tx!=ty){if (dep[tx]>dep[ty]){swop(x,y);swop(tx,ty);}ans=mymax(ans,findmx(1,ys[ty],ys[y]));y=fa[ty];ty=top[y];}if (x==y) return ans;else{if (dep[x]>dep[y]) swop(x,y);return mymax(ans,findmx(1,ys[son[x]],ys[y]));}}void reverse(int x,int y){int tx=top[x],ty=top[y];while (tx!=ty){if (dep[tx]>dep[ty]){swop(x,y);swop(tx,ty);}fanz(1,ys[ty],ys[y]);y=fa[ty];ty=top[y];}if (x==y) return;else {if (dep[x]>dep[y]) swop(x,y);fanz(1,ys[son[x]],ys[y]);}}int main(){//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);int T,i,n,x,y,c;char s[20];scanf("%d",&T);while (T--){scanf("%d",&n);len=0;memset(first,-1,sizeof(first));for (i=1;i<n;i++){scanf("%d%d%d",&x,&y,&c);ins(x,y);ins(y,x);e[i].x=x;e[i].y=y;e[i].c=c;}dep[1]=0;fa[1]=0;dfs1(1);z=0;dfs2(1,1);trlen=0;bt(1,z);for (i=1;i<n;i++) {if (dep[e[i].x]>dep[e[i].y]){int tt=e[i].x;e[i].x=e[i].y;e[i].y=tt;}change(1,ys[e[i].y],e[i].c);}while (1){scanf("\n%s",s);if (s[0]=='Q'){scanf("%d%d",&x,&y);printf("%d\n",query(x,y));}else if (s[0]=='C'){scanf("%d%d",&x,&y);change(1,ys[e[x].y],y);}else if (s[0]=='N'){scanf("%d%d",&x,&y);reverse(x,y);}else if (s[0]=='D') break;}}return 0;}


0 0