poj3237 Tree
题目链接:...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 0x7fffffff struct 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; }