• [LOJ6208]树上询问


    题目大意:
      有一棵n节点的树,根为1号节点。每个节点有两个权值ki,ti,初始值均为0。
      给出三种操作:
        1.Add(x,d)操作:将x到根的路径上所有点的ki←ki+d
        2.Mul(x,d)操作:将x到根的路径上所有点的ti←ti+d×ki
        3.Query(x)操作:询问点x的权值tx

    思路:
      树链剖分以后用线段树维护。
      对于每个结点,我们可以维护3个数a,b,c,表示最后的t为a*b+c。
      对于操作1,需要修改a(修改后的ki)和c(修改的数再乘以b就多了,要从c中减去)。
      对于操作2,需要修改b。
      然后操作3就变成了单点查询。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<vector>
      4 inline int getint() {
      5     register char ch;
      6     register bool neg=false;
      7     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
      8     register int x=ch^'0';
      9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     10     return neg?-x:x;
     11 }
     12 const int N=100001;
     13 std::vector<int> e[N];
     14 inline void add_edge(const int &u,const int &v) {
     15     e[u].push_back(v);
     16     e[v].push_back(u);
     17 }
     18 int n,par[N],son[N],size[N],dep[N],top[N],id[N];
     19 void dfs1(const int &x,const int &par) {
     20     size[x]=1;
     21     ::par[x]=par;
     22     dep[x]=dep[par]+1;
     23     for(unsigned i=0;i<e[x].size();i++) {
     24         const int &y=e[x][i];
     25         if(y==par) continue;
     26         dfs1(y,x);
     27         size[x]+=size[y];
     28         if(size[y]>size[son[x]]) {
     29             son[x]=y;
     30         }
     31     }
     32 }
     33 void dfs2(const int &x) {
     34     id[x]=++id[0];
     35     if(x==son[par[x]]) {
     36         top[x]=top[par[x]];
     37     } else {
     38         top[x]=x;
     39     }
     40     if(son[x]) dfs2(son[x]);
     41     for(unsigned i=0;i<e[x].size();i++) {
     42         const int &y=e[x][i];
     43         if(y==par[x]||y==son[x]) continue;
     44         dfs2(y);
     45     }
     46 }
     47 struct Tag {
     48     int a,b,c;
     49     void operator += (const Tag &another) {
     50         c+=another.c-another.a*b;
     51         a+=another.a;
     52         b+=another.b;
     53     }
     54     int calc() const {
     55         return a*b+c;
     56     }
     57 };
     58 class SegmentTree {
     59     #define _left <<1
     60     #define _right <<1|1
     61     private:
     62         Tag val[N<<2];
     63         void push_down(const int &p) {
     64             val[p _left]+=val[p];
     65             val[p _right]+=val[p];
     66             val[p]=(Tag){0,0,0};
     67         }
     68     public:
     69         void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const Tag &t) {
     70             if(b==l&&e==r) {
     71                 val[p]+=t;
     72                 return;
     73             }
     74             push_down(p);
     75             const int mid=(b+e)>>1;
     76             if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),t);
     77             if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,t);
     78         }
     79         int query(const int &p,const int &b,const int &e,const int &x) {
     80             if(b==e) {
     81                 return val[p].calc();
     82             }
     83             push_down(p);
     84             const int mid=(b+e)>>1;
     85             return x<=mid?query(p _left,b,mid,x):query(p _right,mid+1,e,x);
     86         }
     87     #undef _left
     88     #undef _right
     89 };
     90 SegmentTree t;
     91 inline void modify(int x,const Tag &tag) {
     92     for(;top[x];x=par[top[x]]) {
     93         t.modify(1,1,n,id[top[x]],id[x],tag);
     94     }
     95 }
     96 inline int query(const int &x) {
     97     return t.query(1,1,n,id[x]);
     98 }
     99 int main() {
    100     n=getint();
    101     for(register int i=1;i<n;i++) {
    102         add_edge(getint(),getint());
    103     }
    104     dfs1(1,0);
    105     dfs2(1);
    106     for(register int m=getint();m;m--) {
    107         const int opt=getint(),x=getint();
    108         if(opt==1) modify(x,(Tag){getint(),0,0});
    109         if(opt==2) modify(x,(Tag){0,getint(),0});
    110         if(opt==3) printf("%d
    ",query(x));
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    成为专业程序员路上用到的各种优秀资料、神器及框架
    深度学习的57个专业术语
    Tensorflow实现Mask R-CNN实例分割通用框架,检测,分割和特征点定位一次搞定(多图)
    Python抓取视频内容
    Dataflow编程模型和spark streaming结合
    开启mysql的远程访问
    OpenSSL拒绝服务漏洞(CNVD-2016-01479)
    多款Apple产品libxml2内存破坏漏洞
    Mozilla Network Security Services拒绝服务漏洞
    Linux kernel 'mq_notify'内存错误引用漏洞
  • 原文地址:https://www.cnblogs.com/skylee03/p/8204612.html
Copyright © 2020-2023  润新知