[树套树模板]
询问一条链上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\n", 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 */
给时光以生命,而不是给生命以时光。