zoukankan      html  css  js  c++  java
  • bzoj3730 震波

    题目描述

    题解:

    好像和皮皮鼠那题一模一样。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 100050
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m,v[N],hed[N],cnt;
    struct EG
    {
        int to,nxt;
    }e[2*N];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    int dep[N],fa[N],son[N],siz[N],top[N];
    void dfs1(int u,int f)
    {
        fa[u] = f;
        siz[u] = 1;
        dep[u] = dep[f]+1;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(to==f)continue;
            dfs1(to,u);
            siz[u]+=siz[to];
            if(siz[to]>siz[son[u]])son[u] = to;
        }
    }
    void dfs2(int u,int tp)
    {
        top[u] = tp;
        if(!son[u])return ;
        dfs2(son[u],tp);
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(to==fa[u]||to==son[u])continue;
            dfs2(to,to);
        }
    }
    int get_lca(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])std::swap(x,y);
            x = fa[top[x]];
        }
        return dep[x]<dep[y]?x:y;
    }
    int get_dis(int x,int y)
    {
        return dep[x]+dep[y]-2*dep[get_lca(x,y)];
    }
    int rt,sum,w[N],sz[N],uf[N],mrk[N];
    void get_rt(int u,int f)
    {
        sz[u]=1,w[u]=0;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(mrk[to]||to==f)continue;
            get_rt(to,u);
            sz[u]+=sz[to];
            if(sz[to]>w[u])w[u]=sz[to];
        }
        if(sum-sz[u]>w[u])w[u]=sum-sz[u];
        if(w[u]<w[rt])rt=u;
    }
    void work(int u)
    {
        mrk[u] = 1;int pre = sum;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(mrk[to])continue;
            rt = 0,sum = (sz[to]>sz[u]?pre-sz[u]:sz[to]);
            get_rt(to,0);uf[rt] = u;
            work(rt);
        }
    }
    struct segtree
    {
        int tot,rt[N],ls[N*80],rs[N*80],vl[N*80];
        void insert(int l,int r,int &u,int qx,int d)
        {
            if(!u)u = ++tot;
            vl[u]+=d;
            if(l==r)return ;
            int mid = (l+r)>>1;
            if(qx<=mid)insert(l,mid,ls[u],qx,d);
            else insert(mid+1,r,rs[u],qx,d);
        }
        int query(int l,int r,int u,int qr)
        {
            if(!u)return 0;
            if(r==qr)return vl[u];
            int mid = (l+r)>>1;
            if(qr<=mid)return query(l,mid,ls[u],qr);
            else return vl[ls[u]]+query(mid+1,r,rs[u],qr);
        }
        void push(int x,int qx,int d)
        {
            qx = qx<n?qx:n;
            insert(0,n,rt[x],qx,d);
        }
        int ask(int x,int lim)
        {
            return query(0,n,rt[x],lim);
        }
    }tr1,tr2;
    int main()
    {
        n = rd(),m = rd();
        for(int i=1;i<=n;i++)v[i] = rd();
        for(int f,t,i=1;i<n;i++)
        {
            f = rd(),t = rd();
            ae(f,t),ae(t,f);
        }
        dfs1(1,0),dfs2(1,1);
        w[0]=0x3f3f3f3f,rt=0,sum=n;
        get_rt(1,0);work(rt);
        for(int i=1;i<=n;i++)
        {
            int x = i,y = 0;
            while(x)
            {
                int ds = get_dis(x,i);
                tr1.push(x,ds,v[i]);
                if(y)tr2.push(y,ds,v[i]);
                y=x,x=uf[x];
            }
        }
        int opt,x,y,a,b,ds,ans = 0;
        for(int i=1;i<=m;i++)
        {
            opt = rd(),x = rd()^ans,y = rd()^ans;
            if(!opt)
            {
                a = x,b = 0;
                ans = 0;
                while(a)
                {
                    ds = y - get_dis(a,x);
                    if(ds>=0)
                    {
                        ans+=tr1.ask(a,ds);
                        if(b)ans-=tr2.ask(b,ds);
                    }
                    b = a,a = uf[a];
                }
                printf("%d
    ",ans);
            }else
            {
                int dv = y - v[x];
                v[x] = y;
                a = x,b = 0;
                while(a)
                {
                    ds = get_dis(a,x);
                    tr1.push(a,ds,dv);
                    if(b)tr2.push(b,ds,dv);
                    b = a,a = uf[a];
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    3、字节流输入输出实现文件的copy
    2、io的读出数据到文件中的内容(文件字节输出流)
    1、io的读取文件中的内容(文件字节输入流)
    10 linux中运行jar
    Linux 部署 iSCSI 客户端配置(Linux)
    Linux 部署 iSCSI 服务端
    Linux上使用iSCSI概述
    SSH实现免密登陆
    源码安装Python3
    Windows(受控主机)上配置
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10190491.html
Copyright © 2011-2022 走看看