zoukankan      html  css  js  c++  java
  • [CTSC2008]网络管理 [树剖+整体二分]

    这题的复杂度可以到达惊人的(log^4)据说还能跑过去(差点没吓死我

    直接二分+树剖树套树((n log^4 n))
    一个(log)也不少的4(log)

    但是我有个(log^3)的树剖上面整体二分+线段树的做法

    不过据说有个(log)做法,我不会,反正我菜就是了

    然后的话 就直接考虑个消除贡献…然而并不需要排序

    权值线段树 就可以了

    每次添加修改就

            if(! op) {
    			int y = read() , z = read() ;
    			Q[++ tot] = { 0 , -1 , val[y] , y , 1 } ; val[y] = z ;
    			Q[++ tot] = { 0 , 1 , val[y] , y , 1 } ; b[++ len] = z ;
    		} else {
    			int y = read() , z = read() ; Q[++ tot] = { y , z , op , ++ pos , 2} ;
    		}
    

    然后就成功完成了打消贡献以及添加贡献
    然后整体二分板子即可

    #include <bits/stdc++.h>
    #define int long long
    #define rep(a , b , c) for(int a = b ; a <= c ; ++ a)
    #define Rep(a , b , c) for(int a = b ; a >= c ; -- a)
    #define go(u) for(int i = G.head[u] , v = G.to[i] , w = G.dis[i] ; i ; v = G.to[i = G.nxt[i]] , w = G.dis[i])
    using namespace std ;
    using ll = long long ;
    using pii = pair < int , int > ;
    using vi = vector < int > ;
    int read() {
    	int x = 0 ; bool f = 1 ; char c = getchar() ;
    	while(c < 48 || c > 57) {
    		if(c == '-') f = 0 ;
    		c = getchar() ;
    	}
    	while(c > 47 && c < 58) {
    		x = (x << 1) + (x << 3) + (c & 15) ;
    		c = getchar() ;
    	}
    	return f ? x : -x ;
    }
    template <class T> void print(T x , char c = '
    ') {
    	static char st[100] ; int stp = 0 ;
    	if(! x) putchar('0') ; if(x < 0) x = -x , putchar('-') ;
    	while(x) st[++ stp] = x % 10 ^ 48 , x /= 10 ;
    	while(stp) putchar(st[stp --]) ; putchar(c) ;
    }
    template <class T> void cmax(T & x , T y) { x < y ? x = y : 0 ; }
    template <class T> void cmin(T & x , T y) { x > y ? x = y : 0 ; }
    const int _N = 1e6 + 10 ;
    struct Group {
    	int head[_N] , nxt[_N << 1] , to[_N] , dis[_N] , cnt = 1 ;
    	Group () { memset(head , 0 , sizeof(head)) ; }
    	void add(int u , int v , int w = 1) { nxt[++ cnt] = head[u] ; to[cnt] = v ; dis[cnt] = w ; head[u] = cnt ; }
    } ;
    const int N = 5e5 + 10  ;
    typedef int arr[N] ;
    Group G ;
    int n , q , len = 0 , val[N] , b[N << 1] ;
    arr fa , d , son , sz ;
    void dfs(int u) {
    	sz[u] = 1 ; go(u) if(v ^ fa[u]) {
    		fa[v] = u , d[v] = d[u] + 1 , dfs(v) , sz[u] += sz[v] ; 
    		if(sz[v] > sz[son[u]]) son[u] = v ;
    	}
    }
    arr top , id ;
    int idx = 0 ;
    void dfs(int u , int t) {
    	top[u] = t ;
    	id[u] = ++ idx ;
    	if(son[u]) dfs(son[u] , t) ;
    	go(u) if(v ^ fa[u] && v ^ son[u]) dfs(v , v) ;
    }
    struct Seg {
    	int sum[N << 2] ;
    	void change(int l , int r , int rt , int pos , int val) {
    		if(l == r) { sum[rt] += val ; return ; }
    		int mid = l + r >> 1 ;
    		if(pos <= mid) change(l , mid , rt << 1 , pos , val) ;
    		else change(mid + 1 , r , rt << 1 | 1 , pos , val) ;
    		sum[rt] = sum[rt << 1] + sum[rt << 1 | 1] ;
    	}
    	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 , ans = 0 ;
    		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 ;
    	}
    } t ;
    int query_range(int x , int y) {
    	int ans = 0 ;
    	while(top[x] != top[y]) { if(d[top[x]] < d[top[y]]) swap(x , y) ; ans += t.query(id[top[x]] , id[x] , 1 , n , 1) ; x = fa[top[x]] ; }
    	if(d[x] > d[y]) swap(x , y) ; ans += t.query(id[x] , id[y] , 1 , n , 1) ;
    	return ans ;
    }
    struct Query {
    	int x , y , k , id , type ;
    } Q[N] , q1[N] , q2[N] ;
    int tot = 0 , num = 0 , pos = 0 ;
    arr ans ;
    void solve(int L , int R , int l , int r) {
    	if(L > R) return ;
    	if(l == r) {
    		rep(i , L , R) if(Q[i].type == 2) ans[Q[i].id] = l ; return ;
    	}
    	int mid = l + r >> 1 , cnt1 = 0 , cnt2 = 0 ;
    	rep(i , L , R) {
    		if(Q[i].type == 1) {
    			if(Q[i].k > mid) {
    				t.change(1 , n , 1 , id[Q[i].id] , Q[i].y) ; q2[++ cnt2] = Q[i] ;
    			} else q1[++ cnt1] = Q[i] ;
    		} else {
    			int res = query_range(Q[i].x , Q[i].y) ;
    			if(res >= Q[i].k) q2[++ cnt2] = Q[i] ;
    			else { Q[i].k -= res ; q1[++ cnt1] = Q[i] ; }
    		}
    	}
    	rep(i , 1 , cnt2) if(q2[i].type == 1) t.change(1 , n , 1 , id[q2[i].id] , -q2[i].y) ;
    	rep(i , 1 , cnt1) Q[L + i - 1] = q1[i] ; rep(i , 1 , cnt2) Q[L + cnt1 + i - 1] = q2[i] ;
    	solve(L , L + cnt1 - 1 , l , mid) ; solve(L + cnt1 , R , mid + 1 , r) ;
    }
    signed main() {
    	n = read() ; q = read() ;
    	rep(i , 1 , n) { val[i] = read() ; Q[++ tot] = { 0 , 1 , val[i] , i , 1 } ; b[++ len] = val[i] ; }
    	rep(i , 2 , n) { int x = read() , y = read() ; G.add(x , y) ; G.add(y , x) ; }
    	dfs(1) ; dfs(1 , 1) ;
    	rep(i , 1 , q) {
    		int op = read() ;
    		if(! op) {
    			int y = read() , z = read() ;
    			Q[++ tot] = { 0 , -1 , val[y] , y , 1 } ; val[y] = z ;
    			Q[++ tot] = { 0 , 1 , val[y] , y , 1 } ; b[++ len] = z ;
    		} else {
    			int y = read() , z = read() ; Q[++ tot] = { y , z , op , ++ pos , 2} ;
    		}
    	}
    	sort(b + 1 , b + len + 1) , len = unique(b + 1 , b + len + 1) - b - 1 ;
    	rep(i , 1 , tot) if(Q[i].type != 2) Q[i].k = lower_bound(b + 1 , b + len + 1 , Q[i].k) - b ;
    	solve(1 , tot , 0 , len + 1) ;
    	rep(i , 1 , pos) {
    		if(! ans[i]) puts("invalid request!") ;
    		else print(b[ans[i]]) ;
    	}
    	return 0 ;
    }
    
  • 相关阅读:
    图片自适应居中
    常用正则记录
    继承
    HTML学习
    js原型与原型链理解
    mac 及mac下开发常用快捷键命令
    服务器返回的各种HTTP状态码介绍(转)
    webstorm使用笔记
    《Javascript Dom 高级程序设计》读书笔记
    ECMAScript6学习笔记
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12019610.html
Copyright © 2011-2022 走看看