zoukankan      html  css  js  c++  java
  • [ACM-ICPC 2018 沈阳网络赛] Ka Chang (dfs序+树状数组+分块)

    Given a rooted tree ( the root is node 11 ) of NN nodes. Initially, each node has zero point.

    Then, you need to handle QQ operations. There're two types:

    1 L X1 L X: Increase points by XX of all nodes whose depth equals LL ( the depth of the root is zero ). (x leq 10^8)(x108)

    2 X2 X: Output sum of all points in the subtree whose root is XX.

    Input

    Just one case.

    The first lines contain two integer, N,QN,Q. (N leq 10^5, Q leq 10^5)(N105,Q105).

    The next n-1n1 lines: Each line has two integer aa,bb, means that node aa is the father of node bb. It's guaranteed that the input data forms a rooted tree and node 11 is the root of it.

    The next QQ lines are queries.

    Output

    For each query 22, you should output a number means answer.

    样例输入

    3 3
    1 2
    2 3
    1 1 1
    2 1
    2 3

    样例输出

    1
    0

    SOLUTION:

    第一次写分块这种的暴力的方法qwq
    发现本题 查询子树和 与 修改相同深度的点的val时相互矛盾的
    那就考虑怎么暴力吧

    即,如果修改的那个层数的节点小于某个T,那么就直接用树状数组+DFS序维护子树和,暴力单点更新。

    如果 大于> ,那么就用懒惰标记的思想,先把加了多少 记录下来,等查询的时候再暴力查询该子树,深度为某个值的节点个数,然后乘以该懒惰标记即可。那么这个T多大呢?明显是sqrt(N)。

    那么查询某子树,深度为某个值的节点个数怎么做呢?先把节点按照dfs序编号,然后记录某层有哪些节点,最后二分查询即可。

    CODE:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+7;
    typedef long long ll;
    
    vector<int>G[maxn],dep[maxn],large;
    int st[maxn],ed[maxn],tim,n;
    ll tree[maxn],num[maxn];
    
    void add(int pos,ll v)
    {
        for(;pos<=n;pos+=pos&-pos)
            tree[pos]+=v;
    }
    
    ll query(int pos)
    {
        ll ans=0;
        for(;pos;pos-=pos&-pos)
            ans+=tree[pos];
        return ans;
    }
    
    void dfs(int u,int fa,int depth) //时间戳
    {
        st[u]=++tim;
        dep[depth].push_back(tim);
        int sz=G[u].size();
        for(int i=0;i<sz;i++)
            if(G[u][i]!=fa)
                dfs(G[u][i],u,depth+1);
        ed[u]=tim;
    }
    
    int main()
    {
        int q;
        scanf("%d%d",&n,&q);
        for(int i=0;i<n-1;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,0,0);
    
        int block=ceil(sqrt(n));
        for(int i=0;i<n;i++)
            if(dep[i].size()>block)
                large.push_back(i);
    
        while(q--)
        {
            int nood;
            scanf("%d",&nood);
            if(nood==1)
            {
                int depth;
                ll v;
                scanf("%d%lld",&depth,&v);
                if(dep[depth].size()>block) num[depth]+=v;
                else
                {
                    for(int i=0;i<dep[depth].size();i++)
                        add(dep[depth][i],v);
                }
            }
            else
            {
                int x;
                scanf("%d",&x);
                ll ans=query(ed[x])-query(st[x]-1);
                for(int i=0;i<large.size();i++)
                    ans+=(upper_bound(dep[large[i]].begin(),dep[large[i]].end(),ed[x])-lower_bound(dep[large[i]].begin(),dep[large[i]].end(),st[x]))*num[large[i]];
                printf("%lld
    ",ans);
            }
        }
    }
    

      








  • 相关阅读:
    连接mysql慢或者多台服务器ping不通mysql
    java8 Stream
    Idea 提示xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
    sublime Text的使用
    BigDecimal 加减乘除 比较大小 setScale(精度处理)
    kubectl 命令
    mac brew命令的使用
    mysql json
    idea open打开项目之后,project里没有目录结构。
    mac 多显示器焦点快速切换
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11180202.html
Copyright © 2011-2022 走看看