zoukankan      html  css  js  c++  java
  • [树套树模板]

    [COGS 2282]黑树白

    询问一条链上a<=权值<=b的点有多少个。

    用树剖+树套树水了一下。。(Orz stdafx)

    然而正解并不是酱紫。。

    蛤蛤~

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define maxn 100010
    using namespace std;
    
    int n, m, a[maxn];
    //---------------struct for tree-----------------//
    const int Root = 1;
    struct Edge{int to, nxt;}edge[maxn << 1];
    int h[maxn], cnt;
    void add(int u, int v){
    	cnt ++;
    	edge[cnt].to = v;
    	edge[cnt].nxt = h[u];
    	h[u] = cnt;
    }
    
    int dep[maxn], fa[maxn], top[maxn], s[maxn], son[maxn], pos[maxn];
    int dfs_clock;
    
    void dfs1(int u){
    	s[u] = 1, dep[u] = dep[fa[u]] + 1;
    	for(int i = h[u]; i; i = edge[i].nxt){
    		int v = edge[i].to;
    		if(v == fa[u])continue;
    		fa[v] = u;
    		dfs1(v);
    		s[u] += s[v];
    		if(s[v] > s[son[u]])
    		    son[u] = v;
    	}
    }
    
    void dfs2(int u, int tp){
    	top[u] = tp;
    	pos[u] = ++ dfs_clock;
    	if(son[u])dfs2(son[u], tp);
    	for(int i = h[u]; i; i = edge[i].nxt){
    		int v = edge[i].to;
    		if(v == fa[u] || v == son[u])continue;
    		dfs2(v, v);
    	}
    }
    //-----------------------------------------------//
    #define M 2000010
    int c[M][2], val[M], w[M], size[M], rnd[M], Size;
    int root[maxn << 2];
    
    void pushup(int o){
    	size[o] = size[c[o][0]] + size[c[o][1]] + w[o];
    }
    
    void rotate(int& o, int mark){
    	int cur = c[o][mark];
    	c[o][mark] = c[cur][mark ^ 1];
    	c[cur][mark ^ 1] = o;
    	size[cur] = size[o];
    	pushup(o); o = cur;
    }
    
    int Newnode(int num){
    	int cur = ++ Size;
    	val[cur] = num;
    	rnd[cur] = rand();
    	size[cur] = w[cur] = 1;
    	c[cur][0] = c[cur][1] = 0;
    	return cur;
    }
    
    void Insert(int& o, int num){
    	if(o == 0){o = Newnode(num);return;}
    	size[o] ++;
    	if(val[o] == num){w[o] ++;return;}
    	if(num < val[o]){
    		Insert(c[o][0], num);
    		if(rnd[c[o][0]] > rnd[o])
    		    rotate(o, 0);
    	}
    	else{
    		Insert(c[o][1], num);
    		if(rnd[c[o][1]] > rnd[o])
    		    rotate(o, 1);
    	}
    }
    
    void Delete(int& o, int num){
    	if(val[o] == num){
    		if(w[o] > 1){
    			w[o] --;
    			size[o] --;
    			return;
    		}
    		if(c[o][0] == 0 || c[o][1] == 0)
    		    o = c[o][0] + c[o][1];
    		else if(rnd[c[o][0]] > rnd[c[o][1]])
    		    rotate(o, 0), Delete(o, num);
    		else rotate(o, 1), Delete(o, num);
    		return;
    	}
    	if(num < val[o])Delete(c[o][0], num);
    	else Delete(c[o][1], num);
    	size[o] --;
    }
    #define lc id << 1
    #define rc id << 1 | 1
    void build(int id, int l, int r, int p, int nw){
    	Insert(root[id], nw);
    	if(l == r)return;
    	int mid = l + r >> 1;
    	if(p <= mid)build(lc, l, mid, p, nw);
    	else build(rc, mid+1, r, p, nw);
    }
    
    void change(int id, int l, int r, int p, int nw, int lt){
    	Delete(root[id], lt);
    	Insert(root[id], nw);
    	if(l == r)return;
    	int mid = l + r >> 1;
    	if(p <= mid)change(lc, l, mid, p, nw, lt);
    	else change(rc, mid+1, r, p, nw, lt);
    }
    
    int Find(int o, int nw){
    	if(o == 0)return 0;
    	if(nw >= val[o])return size[c[o][0]] + w[o] + Find(c[o][1], nw);
    	return Find(c[o][0], nw);
    }
    
    int Query(int id, int l, int r, int L, int R, int nw){
    	if(l == L && r == R)return Find(root[id], nw);
    	int mid = l + r >> 1;
    	if(R <= mid)return Query(lc, l, mid, L, R, nw);
    	if(L > mid)return Query(rc, mid+1, r, L, R, nw);
    	return Query(lc, l, mid, L, mid, nw) + Query(rc, mid+1, r, mid+1, R, nw);
    }
    
    int ask(int u, int v, int nw){
    	int ret = 0;
    	while(top[u] != top[v]){
    		if(dep[top[u]] < dep[top[v]])swap(u, v);
    		ret += Query(1, 1, n, pos[top[u]], pos[u], nw);
    		u = fa[top[u]];
    	}
    	if(dep[u] > dep[v])swap(u, v);
    	ret += Query(1, 1, n, pos[u], pos[v], nw);
    	return ret;
    }
    
    int main(){
    	freopen("D_Tree.in", "r", stdin);
    	freopen("D_Tree.out", "w", stdout);
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++)
    	    scanf("%d", &a[i]);
    	int u, v;
    	for(int i = 1; i < n; i ++){
    		scanf("%d%d", &u, &v);
    		add(u, v), add(v, u);
    	}
    	dfs1(Root), dfs2(Root, Root);
    	for(int i = 1; i <= n; i ++)
    	    build(1, 1, n, pos[i], a[i]);
    	int ans = 0; char cmd[2];
    	while(m --){
    		scanf("%s", cmd);
    		if(cmd[0] == 'Q'){
    			int a, b;
    			scanf("%d%d%d%d", &u, &v, &a, &b);
    			u = (u + ans) % n + 1, v = (v + ans) % n + 1;
    			printf("%d
    ", ans = (ask(u, v, b) - ask(u, v, a-1)));
    		}
    		else{
    			scanf("%d%d", &u, &v);
    			u = (u + ans) % n + 1, v = (v + ans) % n + 1;
    			change(1, 1, n, pos[u], v, a[u]), a[u] = v;
    		}
    	}
    	return 0;
    }
    
    /*
    Input
    5 5
    4 3 3 1 1
    2 1
    3 2
    4 3
    5 4
    M 2 1
    M 4 4
    M 1 4
    Q 2 4 2 3
    Q 4 2 1 5
    Output
    1
    4
    */
    

      

    给时光以生命,而不是给生命以时光。
  • 相关阅读:
    关于SQL的一些小知识
    关于VO中的Attribute的问题
    关于JDEV的连接问题
    object xml
    自己写的一个用于往文件中插入字符串及空格的bat
    修改 SQL SERVER 2008 編輯前200筆 資料表問題? 转载自:http://www.dotblogs.com.tw/easy1201/archive/2008/12/04/6179.aspx
    Create Advanced Web Applications With Object-Oriented Techniques
    需求第一
    fwrite() and UTF8 转载
    mysql 表字段与关键字相同的话
  • 原文地址:https://www.cnblogs.com/Candyouth/p/5439484.html
Copyright © 2011-2022 走看看