• BZOJ4034 树上操作


    题目链接:https://vjudge.net/problem/HYSBZ-4034

    知识点:  欧拉序列、线段树

    解题思路:

      先用 $DFS$ 预处理出树的欧拉序列。对于每一个点,如果它是第一次遍历到的,那么就置其 $flag[] = +1$;如果是在回溯时遍历到的,则置其 $flag[] = -1$。如此一来,当执行操作$3$,“询问某个节点 $x$ 到根的路径中所有点的点权和”时,只需查询欧拉序列中 $x$ 首次出现的序号及其之前是所有的点权乘上其相应的 flag 即为答案。

      对于操作$1$,直接将 $x$ 的两个欧拉序列号 $id[x][0], id[x][1]$ 所对应的点加上 $a$ 乘相应的 $flag$ 的值即可;

      对于操作$2$,则将 $[ id[x][0], id[x][1] ]$ 中的所有点加上 $a$ 乘相应的 $flag$ 的值;

      具体操作请看代码,代码中利用一个 $tag[]$ 来记录区间中所有 $flag[]$ 的和,方便区间加操作;$tree[]$ 记录的是区间和。

    AC代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define lson l,m,rt<<1
      4 #define rson m+1,r,rt<<1|1
      5 typedef long long LL;
      6 const int MAXN=100000+5;
      7 
      8 vector<int> G[MAXN];
      9 int pos[MAXN<<1],cnt;
     10 int id[MAXN][2];
     11 LL val[MAXN],flag[MAXN<<1];
     12 LL tree[MAXN<<3],tag[MAXN<<3],lazy[MAXN<<3];
     13 
     14 void dfs(int rt,int last){
     15     cnt++;
     16     pos[cnt]=rt,flag[cnt]=1;
     17     if(!id[rt][0])  id[rt][0]=cnt;
     18     for(int i=0;i<G[rt].size();i++){
     19         int v=G[rt][i];
     20         if(v!=last)
     21             dfs(v,rt);
     22     }
     23     cnt++;
     24     pos[cnt]=rt,flag[cnt]=-1;
     25     id[rt][1]=cnt;
     26 }
     27 void pushup(int rt){
     28     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
     29 }
     30 void pushdown(int rt){
     31     tree[rt<<1]+=lazy[rt]*tag[rt<<1];
     32     tree[rt<<1|1]+=lazy[rt]*tag[rt<<1|1];
     33     lazy[rt<<1]+=lazy[rt],lazy[rt<<1|1]+=lazy[rt];
     34     lazy[rt]=0;
     35 }
     36 void build(int l,int r,int rt){
     37     if(l==r){
     38         tree[rt]=flag[l]*val[pos[l]];
     39         tag[rt]=flag[l];
     40         return;
     41     }
     42     int m=(l+r)/2;
     43     build(lson);    build(rson);
     44     tag[rt]=tag[rt<<1]+tag[rt<<1|1];
     45     pushup(rt);
     46 }
     47 void update(int L,int R,LL val,int l,int r,int rt){
     48     if(L<=l&&r<=R){
     49         lazy[rt]+=val;
     50         tree[rt]+=tag[rt]*val;
     51         return;
     52     }
     53     if(lazy[rt])    pushdown(rt);
     54     int m=(l+r)/2;
     55     if(L<=m)    update(L,R,val,lson);
     56     if(R>m)    update(L,R,val,rson);
     57     pushup(rt);
     58 }
     59 LL query(int L,int R,int l,int r,int rt){
     60     if(L<=l&&r<=R)  return tree[rt];
     61     if(lazy[rt])    pushdown(rt);
     62     int m=(l+r)/2;
     63     LL ret=0;
     64     if(L<=m)    ret+=query(L,R,lson);
     65     if(m<R)     ret+=query(L,R,rson);
     66     return ret;
     67 }
     68 
     69 int main(){
     70 //    freopen("in.txt","r",stdin);
     71     int n,m;
     72     scanf("%d%d",&n,&m);
     73     for(int i=1;i<=n;i++)   scanf("%lld",&val[i]);
     74     for(int i=1;i<n;i++){
     75         int u,v;
     76         scanf("%d%d",&u,&v);
     77         G[u].push_back(v);
     78         G[v].push_back(u);
     79     }
     80     cnt=0;
     81     dfs(1,-1);
     82     build(1,cnt,1);
     83 
     84     while(m--){
     85         int od,x;
     86         LL a;
     87         scanf("%d",&od);
     88         if(od==1){
     89             scanf("%d%lld",&x,&a);
     90             update(id[x][0],id[x][0],a,1,cnt,1);
     91             update(id[x][1],id[x][1],a,1,cnt,1);
     92         }
     93         else if(od==2){
     94             scanf("%d%lld",&x,&a);
     95             update(id[x][0],id[x][1],a,1,cnt,1);
     96         }
     97         else{
     98             scanf("%d",&x);
     99             printf("%lld
    ",query(1,id[x][0],1,cnt,1));
    100         }
    101     }
    102     return 0;
    103 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    模板模式
    简单实用的代理模式
    享元模式
    外观模式(人人都懂的设计模式)
    设计模式之组合模式,温故而知新。
    .net设计模式之装饰模式
    全选、反选
    There is a cycle in the hierarchy解决
    JSONObject、JSONArray
    JsonMessageView工具类
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/9583924.html
Copyright © 2020-2023  润新知