• COJ 1007 WZJ的数据结构(七) 树上操作


    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=983

    WZJ的数据结构(七)
    难度级别:C; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
    试题描述

    给你一棵N个节点的无根树,每个点有一个权值(开始都是0)。请你设计一个数据结构,完成以下功能:

    给你a、b、v,请将a到b路径中的节点权值都增加v(包括a点与b点)。最后输出每个节点的权值。

    输入
    第一行为一个正整数N。
    接下来N-1行为每一条边,每行2个正整数a,b,表示有一条从a到b的边(从1开始编号)。
    第N+1行为一个正整数Q,表示Q次操作。
    接下来Q行为每一次询问,每行3个正整数a、b、v。
    输出
    最后输出每个点的权值,格式见样例。
    输入示例

    2 1
    3 2
    4 3
    3 5
    3 8
    9 8
    8 7
    6 7

    2 5 10 
    4 6 3 
    1 9 5 
    2 7 10 
    5 5 100
    输出示例
    5
    25
    28
    3
    110
    3
    13
    18
    5
    其他说明
    1<=N,Q<=100000

    树链剖分版:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 using namespace std;
     10 const int maxn=100000+10,inf=-1u>>1,maxn3=3*maxn;
     11 struct Tedge{int x,y,w,next;}adj[maxn*2];int ms=0,fch[maxn];
     12 struct Edge{int from,to,dist;}e[maxn];
     13 void AddEdge(int u,int v,int w){adj[++ms]=(Tedge){u,v,w,fch[u]};fch[u]=ms;return;}
     14 int top[maxn],dep[maxn],son[maxn],siz[maxn],fa[maxn],sumv[maxn3],addv[maxn3],num[maxn],sz=0,ql,qr,cv,_sum,n,Q;
     15 void dfs(int u){
     16     siz[u]=1;dep[u]=dep[fa[u]]+1;
     17     for(int i=fch[u];i;i=adj[i].next){
     18         int v=adj[i].y;
     19         if(v!=fa[u]){
     20             fa[v]=u;
     21             dfs(v);
     22             if(siz[son[u]]<siz[v]) son[u]=v;
     23             siz[u]+=siz[v];
     24         }
     25     } return;
     26 }
     27 void build(int u,int tp){
     28     num[u]=++sz;top[u]=tp;
     29     if(son[u]) build(son[u],tp);
     30     for(int i=fch[u];i;i=adj[i].next){
     31         int v=adj[i].y;
     32         if(v!=fa[u]&&v!=son[u]) build(v,v);
     33     } return;
     34 }
     35 void update(int o,int L,int R){
     36     if(ql<=L&&R<=qr) addv[o]+=cv;
     37     else{
     38         int M=L+R>>1,lc=o<<1,rc=lc|1;
     39         if(ql<=M) update(lc,L,M);
     40         if(qr>M) update(rc,M+1,R);
     41     } return;
     42 }
     43 void change(int a,int b){
     44     _sum=0;
     45     int f1=top[a],f2=top[b];
     46     while(f1!=f2){
     47         if(dep[f1]<dep[f2]) swap(f1,f2),swap(a,b);
     48         ql=num[f1];qr=num[a];update(1,1,n);
     49         a=fa[f1];f1=top[a];
     50     }
     51     if(dep[a]>dep[b]) swap(a,b);
     52     ql=num[a];qr=num[b];update(1,1,n);return;//为毛不是孩子了 
     53 }
     54 void clear_set(int o,int L,int R,int add){
     55     if(L==R) sumv[L]+=add+addv[o];
     56     else{
     57         int M=L+R>>1,lc=o<<1,rc=lc|1;
     58         clear_set(lc,L,M,add+addv[o]);
     59         clear_set(rc,M+1,R,add+addv[o]);
     60     } return;
     61 }
     62 inline int read(){
     63     int x=0,sig=1;char ch=getchar();
     64     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
     65     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
     66     return x*=sig;
     67 }
     68 inline void write(int x){
     69     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
     70     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
     71     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
     72 }
     73 void init(){
     74     n=read();
     75     for(int i=1;i<n;i++){
     76         int a=read(),b=read();
     77         AddEdge(a,b,0);AddEdge(b,a,0);
     78         e[i]=(Edge){a,b,0};
     79     }
     80     dfs(1);build(1,1);
     81     for(int i=1;i<n;i++){
     82         if(dep[e[i].from]>dep[e[i].to]) swap(e[i].from,e[i].to);
     83     }
     84     return;
     85 }
     86 void work(){
     87     Q=read();
     88     while(Q--){
     89         int a=read(),b=read(),c=read();
     90         cv=c;change(a,b);
     91     }
     92     return;
     93 }
     94 void print(){
     95     clear_set(1,1,n,0);
     96     for(int i=1;i<=n;i++){
     97         write(sumv[num[i]]);ENT;
     98     }
     99     return;
    100 }
    101 int main(){init();work();print();return 0;}

     LCT

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 using namespace std;
     10 const int maxn=100000+10;
     11 inline int read(){
     12     int x=0,sig=1;char ch=getchar();
     13     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
     14     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
     15     return x*=sig;
     16 }
     17 inline void write(int x){
     18     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
     19     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
     20     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
     21 }
     22 struct node {
     23     node *ch[2],*fa;
     24     bool rev;
     25     int x,sum,siz,mul,add;
     26     inline void add_rev_tag(){
     27         swap(ch[0],ch[1]);rev^=1;return;
     28     }
     29     inline void add_plus_tag(int a){
     30         sum+=siz*a;x+=a;add+=a;return;
     31     }
     32     inline void add_mul_tag(int m){
     33         sum*=m;x*=m;mul*=m;add*=add*m;return;
     34     }
     35     inline void down(){
     36         if(rev){
     37             if(ch[0]) ch[0]->add_rev_tag();
     38             if(ch[1]) ch[1]->add_rev_tag();
     39             rev=0;
     40         }
     41         if(add){
     42             if(ch[0]) ch[0]->add_plus_tag(add);
     43             if(ch[1]) ch[1]->add_plus_tag(add);
     44             add=0;
     45         }
     46         if(mul>1){
     47             if(ch[0]) ch[0]->add_mul_tag(mul);
     48             if(ch[1]) ch[1]->add_mul_tag(mul);
     49             mul=1;
     50         } return;
     51     }
     52     inline void update(){
     53         sum=x;siz=1;
     54         if(ch[0]) sum+=ch[0]->sum,siz+=ch[0]->siz;
     55         if(ch[1]) sum+=ch[1]->sum,siz+=ch[1]->siz;
     56         return;
     57     }
     58 }lct[maxn];
     59 inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[0]==x?0:fa->ch[1]==x?1:-1:-1;}
     60 inline void rotate(node *x){
     61     int t1,t2;
     62     node *fa,*gfa;
     63     t1=get_parent(x,fa);
     64     t2=get_parent(fa,gfa);
     65     if ((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa;
     66     x->ch[t1^1]=fa;fa->fa=x;x->fa=gfa;
     67     if (t2!=-1) gfa->ch[t2]=x;
     68     fa->update();return;
     69 }
     70 inline void pushdown(node *x){
     71     static node *stack[maxn];
     72     int cnt=0;
     73     while(1){
     74         stack[cnt++]=x;
     75         node *fa=x->fa;
     76         if (!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break;
     77         x=fa;
     78     }
     79     while(cnt--) stack[cnt]->down();
     80     return;
     81 }
     82 inline node * splay(node *x){
     83     pushdown(x);
     84     while(1){
     85         int t1,t2;
     86         node *fa,*gfa;
     87         t1=get_parent(x,fa);
     88         if(t1==-1) break;
     89         t2=get_parent(fa,gfa);
     90         if(t2==-1){
     91             rotate(x);break;
     92         } else if (t1==t2){
     93             rotate(fa);rotate(x);
     94         } else{
     95             rotate(x);rotate(x);
     96         }
     97     }
     98     x->update();
     99     return x;
    100 }
    101 inline node * access(node *x){
    102     node *ret=NULL;
    103     while (x) splay(x)->ch[1]=ret,(ret=x)->update(),x=x->fa;
    104     return ret;
    105 }
    106 inline void makeroot(int x){access(lct+x)->add_rev_tag();}
    107 inline void link(int u,int v){
    108     makeroot(u);splay(lct+u)->fa=lct+v;return;
    109 }
    110 inline void cut(int u,int v){
    111     makeroot(u);
    112     node *p=(access(lct+v),splay(lct+v));
    113     p->ch[0]->fa=NULL;
    114     p->ch[0]=NULL;
    115     p->update();
    116 }
    117 int n,q;
    118 int main(){
    119     n=read();
    120     int i;
    121     for(i=1;i<=n;i++) {
    122         lct[i].x=lct[i].sum=0;
    123         lct[i].siz=1;
    124         lct[i].mul=1;
    125         lct[i].add=0;
    126     }
    127     for(i=1;i<n;i++){
    128         int u,v;
    129         u=read();v=read();
    130         link(u,v);
    131     }
    132     q=read();int x,y,c;
    133     while(q--){
    134         x=read();y=read();c=read();
    135         makeroot(x);access(y+lct)->add_plus_tag(c);
    136     }
    137     for(int i=1;i<=n;i++) splay(i+lct),write(lct[i].x),ENT;
    138     /*while(q--){
    139         char ch=getchar();
    140         while(ch<=32) ch=getchar();
    141         int u,v,x,y,c;
    142         if(ch=='+'){
    143             u=read();v=read();c=read();
    144             makeroot(u);
    145             access(lct+v)->add_plus_tag(c);
    146         }else if(ch=='-'){
    147             u=read();v=read();x=read();y=read();
    148             cut(u,v);link(x,y);
    149         }else if(ch=='*'){
    150             u=read();v=read();c=read();
    151             makeroot(u);
    152             access(lct+v)->add_mul_tag(c);
    153         }else if(ch=='/'){
    154             u=read();v=read();
    155             makeroot(u);
    156             printf("%u
    ",access(lct+v)->sum);
    157         }
    158     }*/
    159     return 0;
    160 }
  • 相关阅读:
    【转】Android Hook框架Xposed详解
    【转】不需要 Root,也能用上强大的 Xposed 框架:VirtualXposed
    【转】手把手教你读取Android版微信和手Q的聊天记录(仅作技术研究学习)
    【转】关于音频焦点的理解
    test
    Linux只下载不安装软件包
    Linux用户创建/磁盘挂载相关命令
    telnet的安装配置及xinetd的讨论
    vsftp安装配置教程
    wordpress安装教程
  • 原文地址:https://www.cnblogs.com/chxer/p/4458001.html
Copyright © 2020-2023  润新知