zoukankan      html  css  js  c++  java
  • 51nod_1199 树的先跟遍历+区间更新树状数组

    题目是中文,所以不讲题意

    做法顺序如下:

    1. 使用先跟遍历,把整棵树平铺到一维平面中
    2. 使用自己整的区间更新树状数组模板进行相关操作。
    3. http://www.cnblogs.com/rikka/p/7359185.html

    放代码如下:

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 
      6 /*
      7 *常量MAXN用于设定树状数组的尺寸大小
      8 */
      9 const long long MAXN=500233;
     10 class TreeLikeArray
     11 {
     12     public:
     13 /*
     14 *数组c1用来储存A[i]-A[i-1];
     15 */
     16         long long c1[MAXN];
     17 /*
     18 *数组c2用来储存(A[i]-A[i-1])*(i-1);
     19 *或认为用于储存(i-1)*c1[i];
     20 *两种实现方式完全等价
     21 */
     22         long long c2[MAXN];
     23 /*
     24 *树状数组的常规操作,参数要求传入数组并指明更新位置,以及更新参数。
     25 *树状数组基础底层操作
     26 */
     27         void add(long long array[],long long pos,long long key)
     28     {
     29         while(pos<MAXN)
     30         {
     31             array[pos]+=key;
     32             pos+=pos&(-pos);
     33         }
     34     }
     35 /*
     36 *特别树状数组单点更新操作,要求传入位置和参数
     37 */
     38     void add(long long pos,long long key)
     39     {
     40         
     41         add(c1,pos,key);
     42         add(c1,pos+1,-key);
     43         add(c2,pos,(pos-1)*key);
     44         add(c2,pos+1,-pos*key);
     45         
     46         
     47     }
     48 /*
     49 *特别树状数组多点更新操作,要求传入起始位置、终止位置和参数
     50 *该操作将会使得[pos1,pos2]闭区间内所有元素得到更新
     51 */
     52     void add(long long pos1,long long pos2,long long key)
     53     {
     54         add(c1,pos1,key);
     55         add(c1,pos2+1,-key);
     56         add(c2,pos1,(pos1-1)*key);
     57         add(c2,pos2+1,-pos2*key);
     58     }
     59 /*
     60 *树状数组的常规操作,参数要求传入数组并指明求和位置
     61 *树状数组基础底层操作
     62 */
     63     long long getSum(long long array[],long long pos)
     64     {
     65         long long ret=0;
     66         while(pos>0)
     67         {
     68             ret+=array[pos];
     69             pos-=pos&(-pos);
     70         }return ret;
     71     }
     72 /*
     73 *从起始节点到目标节点闭区间求和[0,i]
     74 */
     75     long long getSum(long long pos)
     76     {
     77         return pos*getSum(c1,pos)-getSum(c2,pos);
     78     }
     79 /*
     80 *求[pos1,pos2]闭区间内元素和
     81 */
     82     long long getSum(long long pos1,long long pos2)
     83     {
     84         return getSum(pos2)-getSum(pos1-1);
     85     }
     86 /*
     87 *求pos单个元素的值
     88 */
     89     long long getSingle(long long pos)
     90     {
     91         return getSum(pos,pos);
     92     }
     93 };
     94 TreeLikeArray TLA;
     95 long long mapp[MAXN];
     96 long long son[MAXN];
     97 long long power[MAXN];
     98 vector<long long >G[MAXN];
     99 long long n,m;
    100 
    101 long long point=1;
    102 void dfs(long long x)
    103 {
    104     mapp[x]=point;
    105     for(int i=0;i<G[x].size();++i)
    106     {
    107         point++;
    108         dfs(G[x][i]);    
    109     }
    110     son[x]=point;
    111 }
    112 
    113 void init()
    114 {
    115     cin>>n>>m;
    116     for(int i=1;i<n;++i)
    117     {
    118         long long a,p;
    119         cin>>a>>p;
    120         G[a].push_back(i);
    121         power[i]=p;
    122     }
    123     dfs(0);
    124     for(int i=0;i<n;++i)
    125     {
    126         TLA.add(mapp[i],power[i]);
    127     } 
    128 }
    129 
    130 int main()
    131 {
    132     cin.sync_with_stdio(false);
    133     
    134     init();
    135     for(int i=0;i<m;++i)
    136     {
    137         char c;
    138         int a,b,z;
    139         cin>>c>>a>>b>>z;
    140         if(c=='S')
    141         {
    142             long long x=TLA.getSingle(mapp[a]);
    143             if(x<b)TLA.add(mapp[a],z);            
    144         }else
    145         {
    146             long long summ=TLA.getSum(mapp[a],son[a]);
    147             if(summ<b*(son[a]-mapp[a]+1))TLA.add(mapp[a],son[a],z);
    148         }
    149     }
    150     for(int i=0;i<n;++i)
    151     {
    152         cout<<TLA.getSingle(mapp[i])<<endl;
    153     }
    154     
    155     return 0;
    156 }
  • 相关阅读:
    事件的解密
    C#世界中的委托
    这次是C#中的接口
    完全二叉树的建立和翻转
    全排列的应用
    网易笔试-按位或运算
    柱状图的最大矩形--单调栈
    Linux将线程绑定到CPU内核运行
    Windows多线程与线程绑定CPU内核
    B+树介绍
  • 原文地址:https://www.cnblogs.com/rikka/p/7361854.html
Copyright © 2011-2022 走看看