zoukankan      html  css  js  c++  java
  • 计蒜客

    题目链接

    18年沈阳网赛的题,一直想补但一直鸽着,终于还是补上了

    一棵树,点带权,支持两种操作:

    1.深度d上的权值加上x

    2.询问子树u下的权值和

    对每个深度按结点数量分类,结点数小于$sqrt(n)$的为1类,其余的为2类

    对于1类深度,修改时暴力修改每个结点的值,查询时用树状数组

    对于2类深度,修改时直接在该深度上打上标记,查询时暴力枚举该结点子树下的每个深度超过$sqrt(n)$的结点

    总复杂度$O((n+q)sqrt(n))$

    其实这道题本质上是一个二维平面上的区间修改查询问题,理论上利用树套树可以将复杂度降至$O((n+q)log^2n)$,但由于题目内存限制得太死所以没法使用(我没试过,有兴趣的话可以试试)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll N=1e5+10,mod=1e9+7,inf=0x3f3f3f3f;
     5 ll n,Q,hd[N],ne,bg[N],ed[N],c[N],tot,cnt[N],sqrtn,sum[N];
     6 unordered_map<ll,ll> mp[N];
     7 vector<ll> vec[N];
     8 struct E {ll v,nxt;} e[N];
     9 ll lb(ll x) {return x&-x;}
    10 ll get(ll u) {ll ret=0; for(; u; u-=lb(u))ret+=c[u]; return ret;}
    11 void add(ll u,ll x) {for(; u<=tot; u+=lb(u))c[u]+=x;}
    12 void link(ll u,ll v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
    13 void dfs1(ll u,ll d=0) {
    14     bg[u]=++tot,cnt[d]++;
    15     for(ll i=hd[u]; ~i; i=e[i].nxt) {
    16         ll v=e[i].v;
    17         dfs1(v,d+1);
    18     }
    19     ed[u]=tot;
    20 }
    21 void dfs2(ll u,ll d=0) {
    22     if(cnt[d]<sqrtn)vec[d].push_back(u);
    23     else mp[u][d]=1;
    24     for(ll i=hd[u]; ~i; i=e[i].nxt) {
    25         ll v=e[i].v;
    26         dfs2(v,d+1);
    27         for(auto x:mp[v])mp[u][x.first]+=x.second;
    28     }
    29 }
    30 ll qry(ll u) {
    31     ll ret=get(ed[u])-get(bg[u]-1);
    32     for(auto x:mp[u])ret+=sum[x.first]*x.second;
    33     return ret;
    34 }
    35 int main() {
    36     memset(hd,-1,sizeof hd),ne=tot=0;
    37     scanf("%lld%lld",&n,&Q),sqrtn=sqrt(n+0.5);
    38     for(ll i=1; i<n; ++i) {
    39         ll u,v;
    40         scanf("%lld%lld",&u,&v);
    41         link(u,v);
    42     }
    43     dfs1(1),dfs2(1);
    44     while(Q--) {
    45         ll f,a,b;
    46         scanf("%lld",&f);
    47         if(f==1) {
    48             scanf("%lld%lld",&a,&b);
    49             if(cnt[a]<sqrtn)for(ll x:vec[a])add(bg[x],b);
    50             else sum[a]+=b;
    51         } else scanf("%lld",&a),printf("%lld
    ",qry(a));
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    AutoCAD快速开发框架之菜单Menu
    AutoCAD快速开发框架之插件Plugin
    探秘AutoCAD中的阵列
    Developing Associative Functionality in AutoCAD(转)
    Getting Block Name from Associative Array(转)
    Developing associative features in AutoCAD(转)
    外部文件创建块
    AutoCAD支持的.NET SDK以及.NET Framework版本
    Flutter异步获取网络数据
    swift使用google admod的横幅,插页式,激励式广告示例
  • 原文地址:https://www.cnblogs.com/asdfsag/p/12392124.html
Copyright © 2011-2022 走看看