zoukankan      html  css  js  c++  java
  • P3950[部落冲突]

    ( ext{这题是个树链剖分的板子题 (好像树剖跑的比 LCT 快)})

    ( ext{这题的操作 : 区间修改 区间查询})

    ( ext{我们考虑题目所说的没有重复的x所以我们不用判重直接干})

    ( ext{所以把每个加法操作即开战存在vector里面 然后结束了直接查询。。})

    ( ext{Yes No 是区间查询 如果能到那个位置 就肯定没有战争即查询的是0})

    (mathcal Code)

    //Isaunoya
    #include<bits/stdc++.h>
    using namespace std ;
    inline int read() { register int x = 0 ; register int f = 1 ; register char c = getchar() ;
    	for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
    	for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
    	return x * f ;
    } int st[105] ;
    template < typename T > inline void write(T x , char c = '
    ') { int tp = 0 ;
    	if(x == 0) return (void) puts("0") ;
    	if(x < 0) putchar('-') , x = -x ;
    	for( ; x ; x /= 10) st[++ tp] = x % 10 ;
    	for( ; tp ; tp --) putchar(st[tp] + '0') ;
    	putchar(c) ;
    }
    //#define Online_Judge
    int n ;
    vector < pair < int , int > > v ;
    const int N = 3e5 + 10 ;
    int a[N] ;
    struct node {
    	int v ;
    	int nxt ;
    };
    node e[N << 1] ; int head[N] ;
    int cnt = 0 ;
    inline void Add(int u , int v) {
    	e[++ cnt].v = v ;
    	e[cnt].nxt = head[u] ;
    	head[u] = cnt ;
    	return ;
    } 
    int size[N] ;
    int top[N] , son[N] ;
    int fa[N] ; int id[N] ; int d[N] ;
    int idx = 0 ;
    inline void Dfs1(int u) {
    	size[u] = 1 ;
    	for(register int i = head[u] ; i ; i = e[i].nxt) {
    		int v = e[i].v ;
    		if(v ^ fa[u]) {
    			fa[v] = u ;
    			d[v] = d[u] + 1 ;
    			Dfs1(v) ;
    			size[u] += size[v] ;
    			if(size[son[u]] < size[v]) son[u] = v ;
    		}
    	}
    }
    inline void Dfs2(int u , int t) {
    	id[u] = ++ idx ;
    	top[u] = t ;
    	a[idx] = 0 ;
    	if(! son[u]) return ;
    	Dfs2(son[u] , t) ;
    	for(register int i = head[u] ; i ; i = e[i].nxt) {
    		int v = e[i].v ;
    		if(v ^ fa[u] && v ^ son[u]) {
    			Dfs2(v , v) ;
    		}
    	}
    }
    int sum[N << 2] ;
    int tag[N << 2] ;
    inline void build(int l , int r , int rt) {
    	if(l == r) {
    		sum[rt] = a[l] ; 
    		tag[rt] = 0 ;
    		return ;
    	}
    	int mid = l + r >> 1 ;
    	build(l , mid , rt << 1) ;
    	build(mid + 1 , r , rt << 1 | 1) ;
    	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1] ;
    	return ;
    }
    inline void Push_down(int rt , int l , int r) {
    	if(tag[rt]) {
    		tag[rt << 1] += tag[rt] ;
    		tag[rt << 1 | 1] += tag[rt] ;
    		int mid = l + r >> 1 ;
    		sum[rt << 1] += tag[rt] * (mid - l + 1) ;
    		sum[rt << 1 | 1] += tag[rt] * (r - mid) ;
    		tag[rt] = 0 ;
    		return ;
    	}
    }
    inline void Change(int a , int b , int l , int r , int rt , int val) {
    	if(a <= l && r <= b) {
    		sum[rt] += val * (r - l + 1) ;
    		tag[rt] += val ;
    		return ;
    	}
    	int mid = l + r >> 1 ;
    	Push_down(rt , l , r) ;
    	if(a <= mid) Change(a , b , l , mid , rt << 1 , val) ;
    	if(b > mid) Change(a , b , mid + 1 , r , rt << 1 | 1 , val) ;
    	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1] ;
    	return ;
    }
    inline int Query(int a , int b , int l , int r , int rt) {
    	if(a <= l && r <= b) return sum[rt] ;
    	int mid = l + r >> 1 ;
    	int ans = 0 ;
    	Push_down(rt , l , r) ;
    	if(a <= mid) ans += Query(a , b , l , mid , rt << 1) ;
    	if(b > mid) ans += Query(a , b , mid + 1 , r , rt << 1 | 1) ;
    	return ans ;
    }
    inline int Query_Range(int x , int y) {
    	int fx = top[x] ;
    	int fy = top[y] ;
    	int ans = 0 ;
    	while(fx ^ fy) {
    		if(d[fx] < d[fy]) swap(x , y) , swap(fx , fy) ;
    		ans += Query(id[fx] , id[x] , 1 , n , 1) ;
    		x = fa[fx] ;
    		fx = top[x] ;
    	}
    	if(id[x] > id[y]) swap(x , y) ;
    	ans += Query(id[x] + 1 , id[y] , 1 , n , 1) ;
    	return ans ;
    }
    inline void Change_Range(int x , int y , int val) {
    	int fx = top[x] ;
    	int fy = top[y] ;
    	int ans = 0 ;
    	while(fx ^ fy) {
    		if(d[fx] < d[fy]) swap(x , y) , swap(fx , fy) ;
    		Change(id[fx] , id[x] , 1 , n , 1 , val) ;
    		x = fa[fx] ;
    		fx = top[x] ;
    	}
    	if(id[x] > id[y]) swap(x , y) ;
    	Change(id[x] + 1 , id[y] , 1 , n , 1 , val) ;
    }
    signed main() {
    #ifdef Online_Judge
    	freopen("testdata.in" , "r" , stdin) ;
    	freopen("testdata2.out" , "w" , stdout) ;
    #endif
    	n = read() ; int q = read() ;
    	for(register int  i = 1 ; i <= n - 1 ; i ++) {
    		int u = read() ;
    		int v = read() ;
    		Add(u , v) ;
    		Add(v , u) ;
    	}
    	Dfs1(1) ;
    	Dfs2(1 , 1) ;
    	build(1 , n , 1) ;
    	for(register int i = 1 ; i <= q ; i ++) {
    		register char c = getchar() ;
    		for( ; c != 'C' && c != 'Q' && c != 'U' ; c = getchar()) ;
    		if(c == 'Q') {
    			int x = read() , y = read() ;
    			if(Query_Range(x , y)) puts("No") ;
    			else puts("Yes") ;
    		}
    		if(c == 'C') {
    			int x = read() , y = read() ;
    			Change_Range(x , y , 1) ;
    			v.push_back(make_pair(x , y)) ;
    		}
    		if(c == 'U') {
    			int num = read() - 1 ;
    			int x = v[num].first ;
    			int y = v[num].second ;
    			Change_Range(x , y , - 1) ;
    		}
    	}
    	return 0 ;
    }
    
  • 相关阅读:
    javascript 设计模式-----观察者模式
    javascript 设计模式-----工厂模式
    javascript 设计模式-----模块模式
    javascript 设计模式-----享元模式
    javascript 设计模式-----策略模式
    js操作Dom的一些方法简化
    Centos7下不删除python2.x的情况下安装python3.x
    解决:Linux SSH Secure Shell(ssh) 超时断开的解决方法
    shell变量常用方法
    apache目录别名
  • 原文地址:https://www.cnblogs.com/qf-breeze/p/11593665.html
Copyright © 2011-2022 走看看