zoukankan      html  css  js  c++  java
  • [SDOI2014]旅行

    Solution

    挺简单的一道题,对每种颜色开一棵动态开点的线段树,然后树剖查询即可。

    就当是复习一下树剖,然后规范一下写法。主要是记录一下代码。

    #include<stdio.h>
    
    const int N=1e5+7;
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    struct Node{
        Node(int ls_=0,int rs_=0,int mx_=0,int s_=0)
        :ls(ls_),rs(rs_),mx(mx_),s(s_){}
        int ls,rs,mx,s;
    }t[N*20];
    
    struct Init{
        int c,w;
    }a[N];
    
    struct E{
        int next,to;
    }e[N<<1];
    
    const int C=1e5;
    int n,Q,in[N];
    int head[N],sz[N],fa[N],son[N],top[N],dep[N];
    
    inline int max(int x,int y){return x>y? x:y;}
    
    inline void add(int id,int to){
        static int cnt=0;
        e[++cnt]=(E){head[id],to};
        head[id]=cnt;
    }
    
    void dfs(int u){
        sz[u]=1;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(v==fa[u]) continue;
            dep[v]=dep[u]+1,fa[v]=u;
            dfs(v),sz[u]+=sz[v];
            if(sz[son[u]]<sz[v]) son[u]=v;
        }
    }
    
    void Dfs(int u,int tp){
        static int cnt=0;
        in[u]=++cnt,top[u]=tp;
        if(!son[u]) return ;
        Dfs(son[u],tp);
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(v==son[u]||v==fa[u]) continue;
            Dfs(v,v);
        }
    }
    
    int W,pos;
    void modify(int &id,int lf=1,int rf=n){
        static int cnt=C;
        if(!id) id=++cnt;
        if(lf==rf){t[id].s+=W,t[id].mx+=W;return;}
        int mid=(lf+rf)>>1;
        if(pos<=mid) modify(t[id].ls,lf,mid);
        else modify(t[id].rs,mid+1,rf);
        t[id].s=t[t[id].ls].s+t[t[id].rs].s;
        t[id].mx=max(t[t[id].ls].mx,t[t[id].rs].mx);
    }
    
    void merge(Node &x,const Node &y){
        x.mx=max(x.mx,y.mx);
        x.s+=y.s;
    }
    
    int L,R;
    Node query(int id,int lf=1,int rf=n){
        if(!id) return (Node){0,0,0,0};
        if(L<=lf&&rf<=R) return t[id];
        int mid=(lf+rf)>>1; Node tmp;
        if(L<=mid) merge(tmp,query(t[id].ls,lf,mid));
        if(R>mid) merge(tmp,query(t[id].rs,mid+1,rf));
        return tmp;
    }
    
    inline void swap(int &x,int &y){x^=y,y^=x,x^=y;}
    Node Query(int u,int v){
        Node ans; int rt=a[u].c;
        while(top[u]!=top[v]){
            if(dep[top[u]]<dep[top[v]]) swap(u,v);
            L=in[top[u]],R=in[u];
            merge(ans,query(rt));
            u=fa[top[u]];
        }
        if(dep[u]<dep[v]) swap(u,v);
        L=in[v],R=in[u],merge(ans,query(rt));
        return ans;
    }
    
    int main(){
        n=read(),Q=read();
        for(int i=1;i<=n;i++)
            a[i].w=read(),a[i].c=read();
        for(int i=1;i<n;i++){
            int u=read(),v=read();
            add(u,v),add(v,u);
        }
        dep[1]=1,dfs(1),Dfs(1,1);
        for(int i=1;i<=n;i++)
            W=a[i].w,pos=in[i],modify(a[i].c);
        char opt[5];
        while(Q--){
            scanf("%s",opt);
            int x=read(),y=read();
            if(opt[1]=='C'){
                W=-a[x].w,pos=in[x],modify(a[x].c);
                W=a[x].w,modify(a[x].c=y);
            }else if(opt[1]=='W')
                W=y-a[x].w,pos=in[x],modify(a[x].c),a[x].w=y;
            else{
                Node p=Query(x,y);
                printf("%d
    ",opt[1]=='S'? p.s:p.mx);
            }
        }
    }
    
  • 相关阅读:
    PEB结构学习
    2016元旦总结
    pwnable.kr的passcode
    PE文件格式(加密与解密3)(一)
    IDA的脚本IDC的一个简单使用
    Python3的tkinter写一个简单的小程序
    2016/12/3-问鼎杯线上赛1-1-Misc
    2016/12/3-问鼎杯线上赛6-2逆向分析
    redis取经之路
    springboot踩坑出坑记
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/14623301.html
Copyright © 2011-2022 走看看