• 51nod 1199 Money out of Thin Air(线段树+树剖分)


    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1199

    题意:

    思路:
    因为是一棵树,所以需要把它剖分一下再映射到线段树上,剖分的话只需要dfs一遍树即可,得到的dfs序就是每个结点在线段树中的位置,子树上的节点的编号都是连续的。

    接下来的操作就是线段树的查询和更新了,这部分并不难。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<stack>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 #include<set>
     11 using namespace std;
     12 typedef long long ll;
     13 const int INF = 0x3f3f3f3f;
     14 const int maxn=50000+5;
     15 
     16 ll n, m, dfs_clock;
     17 int w[maxn],son[maxn],dfn[maxn],num[maxn];
     18 ll lazy[maxn<<2];
     19 
     20 vector<int> G[maxn];
     21 
     22 struct node
     23 {
     24     int l, r;
     25     ll sum;
     26 }t[maxn<<2];
     27 
     28 void dfs(int u)
     29 {
     30     dfn[u]=++dfs_clock;
     31     son[u]=1;
     32     for(int i=0;i<G[u].size();i++)
     33     {
     34         int v=G[u][i];
     35         dfs(v);
     36         son[u]+=son[v];
     37     }
     38 }
     39 
     40 void PushUp(int o)
     41 {
     42     t[o].sum=t[o<<1].sum+t[o<<1|1].sum;
     43 }
     44 
     45 void PushDown(int o)
     46 {
     47     if(lazy[o])
     48     {
     49         lazy[o<<1]+=lazy[o];
     50         lazy[o<<1|1]+=lazy[o];
     51         int m=t[o].r-t[o].l+1;
     52         t[o<<1].sum+=lazy[o]*(m-(m>>1));
     53         t[o<<1|1].sum+=lazy[o]*(m>>1);
     54         lazy[o]=0;
     55     }
     56 }
     57 
     58 void build(int l ,int r, int o)
     59 {
     60     lazy[o]=0;
     61     t[o].l=l;
     62     t[o].r=r;
     63     t[o].sum=0;
     64     if(l==r)
     65     {
     66         t[o].sum=num[l];
     67         return;
     68     }
     69     int mid=(l+r)>>1;
     70     build(l,mid,o<<1);
     71     build(mid+1,r,o<<1|1);
     72     PushUp(o);
     73 }
     74 
     75 void update(int ql, int qr, int l, int r, ll z, int o)
     76 {
     77     if(ql<=l && qr>=r)
     78     {
     79         t[o].sum+=(r-l+1)*z;
     80         lazy[o]+=z;
     81         return;
     82     }
     83     PushDown(o);
     84     int mid=(l+r)>>1;
     85     if(ql<=mid)  update(ql,qr,l,mid,z,o<<1);
     86     if(qr>mid)  update(ql,qr,mid+1,r,z,o<<1|1);
     87     PushUp(o);
     88 }
     89 
     90 ll query(int ql, int qr, int l, int r, int o)
     91 {
     92     if(ql<=l && qr>=r)  return t[o].sum;
     93     PushDown(o);
     94     int mid=(l+r)>>1;
     95     ll ans=0;
     96     if(ql<=mid)  ans+=query(ql,qr,l,mid,o<<1);
     97     if(qr>mid)   ans+=query(ql,qr,mid+1,r,o<<1|1);
     98     return ans;
     99 }
    100 
    101 int main()
    102 {
    103     //freopen("in.txt","r",stdin);
    104     scanf("%d%d",&n,&m);
    105     for(int i=0;i<n;i++)  G[i].clear();
    106     for(int i=1;i<n;i++)
    107     {
    108         int p; scanf("%d%d",&p,&w[i]);
    109         G[p].push_back(i);
    110     }
    111     w[0]=0;
    112     dfs_clock=0;
    113     dfs(0);
    114     for(int i=0;i<n;i++)  num[dfn[i]]=w[i];
    115     build(1,n,1);
    116     char op[3]; ll x, y, z;
    117     memset(lazy,0,sizeof(lazy));
    118     while(m--)
    119     {
    120         scanf("%s%lld%lld%lld",op,&x,&y,&z);
    121         if(op[0]=='S')
    122         {
    123             if(query(dfn[x],dfn[x],1,n,1)<y)  update(dfn[x],dfn[x],1,n,z,1);
    124         }
    125         else
    126         {
    127             if(query(dfn[x],dfn[x]+son[x]-1,1,n,1)<son[x]*y)  update(dfn[x],dfn[x]+son[x]-1,1,n,z,1);
    128         }
    129     }
    130     for(int i=0;i<n;i++)  printf("%lld
    ",query(dfn[i],dfn[i],1,n,1));
    131     return 0;
    132 }
  • 相关阅读:
    ADV-拍卖
    poj1190生日蛋糕--DFS
    poj1562-DFS
    二叉树--先序中序遍历求后序遍历
    poj1753-Flip Game DFS解法
    Baby-gin
    OX Pattern
    C
    qi qiu

  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7435120.html
Copyright © 2020-2023  润新知