旅游(国家集训队)

来源:互联网 发布:html的js加减怎么做 编辑:程序博客网 时间:2024/05/03 03:53

题面

树链剖分,边权存到点上,注意边界处理

#include<iostream>#include<cstdio>#include<cstring>#define maxn 100005using namespace std;int n,m;struct edge{    int to,ne,w;  }b[maxn];int k=0,head[maxn];struct tree{    int l,r,mx,mi,sum; }t[maxn*4];struct edge2{     int s,t,w; }a[maxn];int c[maxn];bool rev[maxn];int max(int x,int y){    return x >y ? x: y;}void swap(int &x,int &y){    int z=x;x=y;y=z; }inline int read(){     int x=0;char ch=getchar();     while(ch<'0'||ch>'9') ch=getchar();     while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }     return x;  }void add(int u,int v,int w){    k++;    b[k].to=v;b[k].ne=head[u];b[k].w=w;head[u]=k;}int fa[maxn],sz[maxn],son[maxn],d[maxn],top[maxn],id[maxn],pos[maxn];void dfs1(int x){    sz[x]=1;     for(int i=head[x];i!=-1;i=b[i].ne)    if(b[i].to!=fa[x]){       fa[b[i].to]=x; d[b[i].to]=d[x]+1;       c[b[i].to]=b[i].w;       dfs1(b[i].to);       sz[x]+=sz[b[i].to];       if(son[x]==-1) son[x]=b[i].to;       else if(sz[b[i].to]>sz[son[x]]) son[x]=b[i].to;    }}int cnt=0;void dfs2(int x,int tp){     id[x]=++cnt;  pos[cnt]=x;     top[x]=tp;     if(son[x]!=-1) dfs2(son[x],tp);     for(int i=head[x];i!=-1;i=b[i].ne)     if(b[i].to!=fa[x]&&b[i].to!=son[x])  dfs2(b[i].to,b[i].to);}struct  Tree{        void swp(int &x,int &y)        {             int z=x; x=-y; y=-z;        }        void update(int z)        {            t[z].mx=max(t[z<<1].mx,t[z<<1|1].mx);            t[z].mi=min(t[z<<1].mi,t[z<<1|1].mi);            t[z].sum=t[z<<1].sum+t[z<<1|1].sum;         }        void build(int l,int r,int z)        {            t[z].l=l;t[z].r=r;            if(l==r){               t[z].mx=t[z].mi=t[z].sum=c[pos[l]];               return ;            }            int mid=(l+r)>>1;            build(l,mid,z<<1);            build(mid+1,r,z<<1|1);            update(z);        }        void xg(int x,int y,int z)        {            if(t[z].l==t[z].r){               t[z].mx=t[z].mi=t[z].sum=y;               return ;            }            int mid=(t[z].l+t[z].r)>>1;            if(x<=mid) xg(x,y,z<<1);            else xg(x,y,z<<1|1);            update(z);        }        void Rev(int x,int y,int z)        {             if(t[z].l==t[z].r){                t[z].mx*=-1;t[z].mi*=-1;t[z].sum*=-1;                return ;             }             int mid=(t[z].l+t[z].r)>>1;             if(x<=mid) Rev(x,y,z<<1);             if(y>mid) Rev(x,y,z<<1|1);             update(z);        }        int getsum(int x,int y,int z)        {             if(x<=t[z].l&&t[z].r<=y) return t[z].sum;             int ans=0;             int mid=(t[z].l+t[z].r)>>1;             if(x<=mid) ans+=getsum(x,y,z<<1);             if(y>mid) ans+=getsum(x,y,z<<1|1);             return ans;        }        int getmax(int x,int y,int z)        {             if(x<=t[z].l&&t[z].r<=y) return t[z].mx;             int ans=-0x7fffffff;             int mid=(t[z].l+t[z].r)>>1;             if(x<=mid) ans=max(ans,getmax(x,y,z<<1));             if(y>mid) ans=max(ans,getmax(x,y,z<<1|1));             return ans;        }           int getmin(int x,int y,int z)        {             if(x<=t[z].l&&t[z].r<=y) return t[z].mi;             int ans=0x7fffffff;             int mid=(t[z].l+t[z].r)>>1;             if(x<=mid) ans=min(ans,getmin(x,y,z<<1));             if(y>mid) ans=min(ans,getmin(x,y,z<<1|1));             return ans;        }   }tr;void revc(int x,int y){     int fx=top[x],fy=top[y];     while(fx!=fy){        if(d[fx]<d[fy])  { swap(fx,fy); swap(x,y); }        tr.Rev(id[fx],id[x],1);        x=fa[fx]; fx=top[x];     }     if(d[x]>d[y]) swap(x,y);     tr.Rev(id[x]+1,id[y],1);}int getsum(int x,int y){     int fx=top[x],fy=top[y];     int ans=0;     while(fx!=fy){         if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); }         ans+=tr.getsum(id[fx],id[x],1);         x=fa[fx]; fx=top[x];     }     if(d[x]>d[y]) swap(x,y);     ans+=tr.getsum(id[x]+1,id[y],1);     return ans;}int getmax(int x,int y){     int fx=top[x],fy=top[y];     int ans=-0x7fffffff;     while(fx!=fy){         if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); }         ans=max(ans,tr.getmax(id[fx],id[x],1));         x=fa[fx]; fx=top[x];     }     if(d[x]>d[y]) swap(x,y);     ans=max(ans,tr.getmax(id[x]+1,id[y],1));     return ans;}int getmin(int x,int y){     int fx=top[x],fy=top[y];     int ans=0x7fffffff;     while(fx!=fy){         if(d[fx]<d[fy]) { swap(fx,fy); swap(x,y); }         ans=min(ans,tr.getmin(id[fx],id[x],1));         x=fa[fx]; fx=top[x];     }     if(d[x]>d[y]) swap(x,y);     ans=min(ans,tr.getmin(id[x]+1,id[y],1));     return ans;}int main(){    //freopen("in.txt","r",stdin);    freopen("nt2011_travel.in","r",stdin);    freopen("nt2011_travel.out","w",stdout);    memset(head,-1,sizeof(head));    memset(son,-1,sizeof(son));    memset(fa,-1,sizeof(fa));    scanf("%d",&n);    int x,y,z;    char type[5];    for(int i=1;i<n;i++){       scanf("%d%d%d",&x,&y,&z);       add(x,y,z);  add(y,x,z);       a[i].s=x;a[i].t=y;    }    dfs1(0);    dfs2(0,0);    tr.build(1,n+1,1);    scanf("%d",&m);    while(m--){        scanf("%s",type); scanf("%d%d",&x,&y);        if(type[0]=='C'){           if(fa[a[x].s]==a[x].t) tr.xg(id[a[x].s],y,1);           else  tr.xg(id[a[x].t],y,1);        }        if(type[0]=='N')  revc(x,y);         if(type[0]=='S')  printf("%d\n",getsum(x,y));         if(type[0]=='M'&&type[1]=='A') printf("%d\n",getmax(x,y));        if(type[0]=='M'&&type[1]=='I') printf("%d\n",getmin(x,y));    }    return 0;}


原创粉丝点击