• 51Nod 1199 Money out of Thin Air(dfs序加线段树)


    http://www.51nod.com/Challenge/Problem.html#!#problemId=1199

    又wa了一下午。。。

    思路

    树的先序遍历顺序刚好对应线段树的一个区间,利用这一点直接dfs建序,然后再建线段树来查询修改就可以了。

      1 #define dbg(x) cout<<#x<<" = "<< (x)<< endl
      2 #define IO std::ios::sync_with_stdio(0);
      3 #include <bits/stdc++.h>
      4 #define iter ::iterator
      5 using namespace  std;
      6 typedef long long ll;
      7 typedef pair<ll,ll>P;
      8 #define pb push_back
      9 #define se second
     10 #define fi first
     11 #define rs o<<1|1
     12 #define ls o<<1
     13 const ll inf=0x7fffffff;
     14 const int N=5e4+10;
     15 int l1[N],r1[N],fa[N];
     16 ll w[N],t[N];
     17 vector<int>g[N];
     18 int n,q,cnt;
     19 struct node{
     20     ll sumv,add;
     21 }a[N*4];
     22 void dfs(int u){
     23     l1[u]=++cnt;
     24     t[cnt]=u;
     25     for(int i=0;i<g[u].size();i++){
     26         int v=g[u][i];
     27         if(v==fa[u])continue;
     28         dfs(v);
     29     }
     30     r1[u]=cnt;
     31 }
     32 void push(int o){
     33     a[o].sumv=a[ls].sumv+a[rs].sumv;
     34 }
     35 void down(int o,int l,int r){
     36     if(a[o].add){
     37         a[ls].add+=a[o].add;
     38         a[rs].add+=a[o].add;
     39         int m=(l+r)/2;
     40         a[ls].sumv+=1ll*a[o].add*(m-l+1);
     41         a[rs].sumv+=1ll*a[o].add*(r-m);
     42         a[o].add=0;
     43     }
     44 }
     45 void build(int o,int l,int r){
     46     if(l==r){
     47         a[o].sumv=w[t[l]];
     48         return;
     49     }
     50     int m=(l+r)/2;
     51     build(ls,l,m);
     52     build(rs,m+1,r);
     53     push(o);
     54 }
     55 void up(int o,int l,int r,int ql,int qr,ll k){
     56     if(l>=ql&&r<=qr){
     57         a[o].sumv+=1ll*(r-l+1)*k;
     58         a[o].add+=k;
     59         return;
     60     }
     61     down(o,l,r);
     62     int m=(l+r)/2;
     63     if(ql<=m)up(ls,l,m,ql,qr,k);
     64     if(qr>m)up(rs,m+1,r,ql,qr,k);
     65     push(o);
     66 }
     67 ll qu(int o,int l,int r,int ql,int qr){
     68     if(l>=ql&&r<=qr){
     69         return a[o].sumv;
     70     }
     71     down(o,l,r);
     72     int m=(l+r)/2;
     73     ll res=0;
     74     if(ql<=m)res+=qu(ls,l,m,ql,qr);
     75     if(qr>m)res+=qu(rs,m+1,r,ql,qr);
     76     return res;
     77 }
     78 int main(){
     79     scanf("%d%d",&n,&q);
     80     for(int i=2;i<=n;i++){
     81         scanf("%d%lld",&fa[i],&w[i]);
     82         fa[i]++;
     83         g[fa[i]].pb(i);
     84     }
     85     dfs(1);
     86     build(1,1,cnt);
     87     while(q--){
     88         char s[10];
     89         scanf("%s",s);
     90         ll x,y,z;
     91         scanf("%d%lld%lld",&x,&y,&z);
     92         x++;
     93         if(s[0]=='A'){
     94             ll res=qu(1,1,cnt,l1[x],r1[x]);
     95             ll h=r1[x]-l1[x]+1;
     96             if(res<1ll*y*h){
     97                 up(1,1,cnt,l1[x],r1[x],z);
     98             }
     99         }
    100         else{
    101             ll res=qu(1,1,cnt,l1[x],l1[x]);
    102             if(res<y){
    103                 up(1,1,cnt,l1[x],l1[x],z);
    104             }
    105         }
    106     }
    107     for(int i=1;i<=n;i++){
    108         printf("%lld
    ",qu(1,1,cnt,l1[i],l1[i]));
    109     }
    110 }
  • 相关阅读:
    判断IE浏览器的版本号
    解决下拉框第一行出现空格的问题
    Springboot整合log4j2日志全解
    Java NIO之Selector(选择器)
    ZooKeeper客户端 zkCli.sh 节点的增删改查
    Java API操作ZooKeeper
    ReentrantLock(重入锁)功能详解和应用演示
    MySQL高可用集群方案
    Redis高可用之集群配置(六)
    linux free命令详解
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/10666479.html
Copyright © 2020-2023  润新知