hdu 3966 树链剖分模版
来源:互联网 发布:申请网络空间 编辑:程序博客网 时间:2024/05/16 12:12
#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;typedef long long LL ;const int maxn = 50008 ;int n ;int siz[maxn] , top[maxn] , son[maxn] ;int dep[maxn] , tid[maxn] , rank[maxn] , fa[maxn] ;int head[maxn] , to[maxn*2] , next[maxn*2] , edge ;int tim ;void init(){ memset(head , -1 , sizeof(head)) ; memset(son , -1 , sizeof(son)) ; tim = edge = 0 ;}void addedge(int u , int v){ to[edge] = v , next[edge] = head[u] , head[u] = edge++ ; to[edge] = u , next[edge] = head[v] , head[v] = edge++ ;}void dfs1(int u , int father , int d){ dep[u] = d ; fa[u] = father ; siz[u] = 1 ; for(int i = head[u] ; i != -1 ; i = next[i]){ int v = to[i] ; if(v != father){ dfs1(v , u , d+1) ; siz[u] += siz[v] ; if(son[u] == -1 || siz[v] > siz[son[u]]) son[u] = v ; } }}void dfs2(int u , int tp){ top[u] = tp ; tid[u] = ++tim ; rank[tid[u]] = u ; if(son[u] == -1) return ; dfs2(son[u] , tp) ; for(int i = head[u] ; i != -1 ; i = next[i]){ int v = to[i] ; if(v != son[u] && v != fa[u]) dfs2(v , v) ; }}LL sum[maxn<<2] , add[maxn<<2] , a[maxn] ;void up(int t){ sum[t] = sum[t<<1] + sum[t<<1|1] ;}void down(int t , int l , int r){ if(add[t]){ int m = (l + r) >> 1 ; add[t<<1] += add[t] ; add[t<<1|1] += add[t] ; sum[t<<1] += add[t] * LL(m-l+1) ; sum[t<<1|1] += add[t] * LL(r - m) ; add[t] = 0 ; }}void make(int l , int r , int t){ add[t] = 0 ; if(l == r){ sum[t] = a[rank[l]] ; return ; } int m = (l + r) >> 1 ; make(l , m , t<<1) ; make(m+1 , r , t<<1|1) ; up(t) ;}void update(int L , int R , LL c , int l , int r , int t){ if(L <= l && r <= R){ add[t] += c ; sum[t] += c * LL(r - l + 1) ; return ; } down(t , l , r) ; int m = (l + r) >> 1 ; if(L <= m) update(L , R , c , l , m , t<<1) ; if(R > m) update(L , R , c , m+1 , r , t<<1|1) ; up(t) ;}LL ask(int l , int r , int t , int x){ if(l == r) return sum[t] ; down(t , l , r) ; int m = (l + r) >> 1 ; if(x <= m) return ask(l , m , t<<1 , x) ; else return ask(m+1 , r , t<<1|1 , x) ;}void change(int x , int y , LL c){ while(top[x] != top[y]){ if(dep[top[x]] < dep[top[y]]) swap(x , y) ; update(tid[top[x]] , tid[x] , c , 1 , n , 1) ; x = fa[top[x]] ; } if(dep[x] > dep[y]) swap(x , y) ; update(tid[x] , tid[y] , c , 1 , n , 1) ;}int main(){ int m , q , u , v , i , l , r ; LL c ; char s[2] ; while(scanf("%d%d%d" , &n , &m , &q) != EOF){ for(i = 1 ; i <= n ; i++) scanf("%I64d" , &a[i]) ; init() ; while(m--){ scanf("%d%d" , &u , &v) ; addedge(u , v) ; } dfs1(1 , 0 , 0) ; dfs2(1 , 1) ; make(1 , n , 1) ; while(q--){ scanf("%s" , s) ; if(s[0] == 'Q'){ scanf("%d" , &i) ; printf("%I64d\n" , ask(1 , n , 1 , tid[i])) ; } else{ scanf("%d%d%I64d" , &l , &r , &c) ; if(s[0] == 'D') c = -c ; change(l , r , c) ; } } } return 0 ;}
0 0
- hdu 3966 树链剖分模版
- hdu 3966 树链刨分 模版题
- HDU 1711 KMP模版
- HDU - 3966 Aragorn's Story(树剖模版题)
- 树链剖分模版
- 树链剖分模版
- 树链剖分模版
- 树链剖分 模版
- 树链剖分模版
- Hdu 1532 网络流模版
- hdu 2222 ac自动机模版
- HDU 2222 AC自动机模版
- 伸展树模版题 hdu
- hdu 1034 A*算法模版
- hdu 4501 多维背包模版
- hdu 1402 (FFT 模版)
- hdu 5011 (nim博弈模版)
- hdu 2063 过山车 裸模版
- Android注册监听函数的NullPointerException
- 运算和阵列
- android - 自定义标题栏(在标题栏中增加按钮和文本居中)
- jQuery easyui datagrid 的数据加载
- 【产品经理】产品经理之我述
- hdu 3966 树链剖分模版
- forward和redirect的区别
- CubieTruck Debian打开WIFI方法
- 深度学习:Hinton_Science_Reducing the dimensionality of data with neural networks
- 直线检测算法 LSD 的相关介绍及其在 OpenCV 和 MATLAB 中的可视化
- Linux 防火墙开放特定端口 (iptables)
- 中文输入程序
- C++中虚函数的原理和虚函数表
- IE 设置ActiveX每次加载都是上一次的内容,怎么办?