zoukankan      html  css  js  c++  java
  • BZOJ4999 This Problem Is Too Simple!(树上差分+dfs序+树状数组)

      对每个权值分别考虑。则只有单点加路径求和的操作。树上差分转化为求到根的路径和,子树加即可。再差分后bit即可。注意树上差分中根的父亲是0,已经忘了是第几次因为这个挂了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 100010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,a[N],p[N],dfn[N],size[N],deep[N],fa[N][19],tree[N],ans[N*5],t,cnt;
    struct data{int to,nxt;
    }edge[N<<1];
    struct data2
    {
        int op,i,j,x,id;
        bool operator <(const data2&a) const
        {
            return x<a.x||x==a.x&&id<a.id;
        }
    }q[N*5];
    void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
    void dfs(int k)
    {
        dfn[k]=++cnt,size[k]=1;
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=fa[k][0])
        {
            deep[edge[i].to]=deep[k]+1;
            fa[edge[i].to][0]=k;
            dfs(edge[i].to);
            size[k]+=size[edge[i].to];
        }
    }
    void add(int k,int x){while (k<=n) tree[k]+=x,k+=k&-k;}
    int query(int k) {int s=0;while (k) s+=tree[k],k-=k&-k;return s;}
    int lca(int x,int y)
    {
        if (deep[x]<deep[y]) swap(x,y);
        for (int j=18;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];
        if (x==y) return x;
        for (int j=18;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
        return fa[x][0];
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4999.in","r",stdin);
        freopen("bzoj4999.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();
        for (int i=1;i<=n;i++) a[i]=read();
        for (int i=1;i<n;i++)
        {
            int x=read(),y=read();
            addedge(x,y),addedge(y,x);
        }
        fa[1][0]=1;dfs(1);
        for (int j=1;j<19;j++)
            for (int i=1;i<=n;i++)
            fa[i][j]=fa[fa[i][j-1]][j-1];
        int x=0;
        for (int i=1;i<=n;i++) x++,q[x].op=0,q[x].i=i,q[x].j=1,q[x].x=a[i],q[x].id=x;
        for (int i=1;i<=m;i++)
        {
            char c=getc();
            if (c=='C')
            {
                x++,q[x].op=0,q[x].i=read(),q[x].j=1,q[x].x=read(),q[x].id=x;
                x++,q[x].op=0,q[x].i=q[x-1].i,q[x].j=-1,q[x].x=a[q[x].i],q[x].id=x;
                a[q[x].i]=q[x-1].x;
            }
            else x++,q[x].op=1,q[x].i=read(),q[x].j=read(),q[x].x=read(),q[x].id=x;
        }
        m=x;
        sort(q+1,q+m+1);memset(ans,255,sizeof(ans));
        for (int i=1;i<=m;i++)
        {
            int t=i;
            while (t<m&&q[t+1].x==q[i].x) t++;
            for (int j=i;j<=t;j++)
            if (q[j].op)
            {
                int l=lca(q[j].i,q[j].j);
                ans[q[j].id]=query(dfn[q[j].i])+query(dfn[q[j].j])-query(dfn[l])-query(dfn[l==1?0:fa[l][0]]);
            }
            else add(dfn[q[j].i],q[j].j),add(dfn[q[j].i]+size[q[j].i],-q[j].j);
            for (int j=i;j<=t;j++)
            if (q[j].op==0) add(dfn[q[j].i],-q[j].j),add(dfn[q[j].i]+size[q[j].i],q[j].j);
            i=t;
        }
        for (int i=1;i<=m;i++) if (ans[i]>=0) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    mysql数据库常用指令
    解决windows的mysql无法启动 服务没有报告任何错误的经验。
    “Can't open file for writing”或“operation not permitted”的解决办法
    启动Apache出现错误Port 80 in use by "Unable to open process" with PID 4!
    如何打开windows的服务services.msc
    常见的HTTP状态码 404 500 301 200
    linux系统常用的重启、关机指令
    (wifi)wifi移植之命令行调试driver和supplicant
    linux(debian)安装USB无线网卡(tp-link TL-WN725N rtl8188eu )
    alloc_chrdev_region申请一个动态主设备号,并申请一系列次设备号
  • 原文地址:https://www.cnblogs.com/Gloid/p/10055277.html
Copyright © 2011-2022 走看看