bzoj4999: This Problem Is Too Simple!
2018-01-03 20:58
369 查看
题面在这里
1. C i x(0<=x<2^31) 表示将i节点的值改为x。
2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。
每个数值都维护一棵线段树。
不想离散可以用map偷懒。。。
题意:
给一棵树,现在支持以下两种操作:1. C i x(0<=x<2^31) 表示将i节点的值改为x。
2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。
做法:
树链剖分+动态开点线段树。每个数值都维护一棵线段树。
不想离散可以用map偷懒。。。
代码:
/************************************************************* Problem: bzoj 4999 This Problem Is Too Simple! User: fengyuan Language: C++ Result: Accepted Time: 5596 ms Memory: 245664 kb Submit_Time: 2018-01-03 20:45:26 *************************************************************/ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<cctype> #include<map> #define mid (l+r>> 4000 ;1) #define lc o<<1 #define rc o<<1|1 using namespace std; typedef long long LL; inline LL read() { char ch = getchar(); LL x = 0; int op = 1; for(; !isdigit(ch); ch = getchar()) if(ch == '-') op = -1; for(; isdigit(ch); ch = getchar()) x = x*10 + ch-'0'; return x*op; } inline void writeabs(LL a) { if(a >= 10) writeabs(a/10); putchar(a%10+'0'); } inline void write(LL a) { if(a < 0) putchar('-'); writeabs(abs(a)); } const int N = 100010, M = 20000010; int n, m, total, cnt, clk, all; int a , head , depth , fa , sz , son , in , top ; int rt[N<<2], L[M], R[M], sum[M]; char opt[4]; map<int, int> MP; struct Edge{ int to, nex; Edge() {} Edge(int x, int y) { to = x, nex = y; } }e[N<<1]; inline int get(int x) { if(MP.count(x)) return MP[x]; MP[x] = ++ all; return all; } inline void addEdge(int x, int y) { e[++ cnt] = Edge(y, head[x]); head[x] = cnt; } inline void dfs(int u, int lst, int s) { depth[u] = s; fa[u] = lst; sz[u] = 1; for(int i = head[u]; i; i = e[i].nex){ int v = e[i].to; if(v == lst) continue; dfs(v, u, s+1); sz[u] += sz[v]; if (sz[v] > sz[son[u]]) son[u] = v; } } inline void dfs2(int u, int t) { in[u] = ++ clk; top[u] = t; if(son[u]) dfs2(son[u], t); for(int i = head[u]; i; i = e[i].nex) if(e[i].to != son[u] && e[i].to != fa[u]) dfs2(e[i].to, e[i].to); } inline void update(int &o, int l, int r, int x, int y) { if(!o) o = ++ total; if(l == r) { sum[o] += y; return; } if(x <= mid) update(L[o], l, mid, x, y); else update(R[o], mid+1, r, x, y); sum[o] = sum[L[o]] + sum[R[o]]; } inline int getsum(int o, int l, int r, int x, int y) { if(!o) return 0; if(l == x && r == y) return sum[o]; if(y <= mid) return getsum(L[o], l, mid, x, y); else if(x > mid) return getsum(R[o], mid+1, r, x, y); else return getsum(L[o], l, mid, x, mid) + getsum(R[o], mid+1, r, mid+1, y); } inline int qry(int x, int y, int z) { int ret = 0; while(top[x] != top[y]) { if(depth[top[x]] < depth[top[y]]) swap(x, y); ret += getsum(rt[z], 1, n, in[top[x]], in[x]); x = fa[top[x]]; } if(depth[x] > depth[y]) swap(x, y); ret += getsum(rt[z], 1, n, in[x], in[y]); return ret; } int main() { n = read(), m = read(); for(int i = 1; i <= n; i ++) a[i] = read(); for(int i = 1; i < n; i ++) { int x = read(), y = read(); addEdge(x, y); addEdge(y, x); } dfs(1, 0, 0); dfs2(1, 1); for(int i = 1; i <= n; i ++) { a[i] = get(a[i]); update(rt[a[i]], 1, n, in[i], 1); } while(m --) { scanf("%s", opt); int x = read(), y = read(), z; if(opt[0] == 'C') { update(rt[a[x]], 1, n, in[x], -1); a[x] = get(y); update(rt[a[x]], 1, n, in[x], 1); } else { z = read(); if(!MP.count(z)) puts("0"); else write(qry(x, y, MP[z])), puts(""); } } return 0; }
相关文章推荐
- bzoj 4999: This Problem Is Too Simple!
- [BZOJ]4999: This Problem Is Too Simple! 树链剖分
- 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA
- BZOJ 4999: This Problem Is Too Simple!
- bzoj 4999: This Problem Is Too Simple!
- bzoj 4999 This problem is too simple 树链剖分+动态开点线段树
- 【bzoj4999】This Problem Is Too Simple!
- 【BZOJ4999】This Problem Is Too Simple!(线段树)
- 【BZOJ4999】This Problem Is Too Simple!(线段树)
- 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树
- bzoj 4999: This Problem Is Too Simple! 树链剖分+线段树
- bzoj4999 This Problem Is Too Simple!(树链剖分+动态开点线段树)
- bzoj 4999: This Problem Is Too Simple!
- BZOJ[4999]This Problem Is Too Simple! 树链剖分
- BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树
- BZOJ4999: This Problem Is Too Simple!
- 4999: This Problem Is Too Simple!
- 4999: This Problem Is Too Simple!
- bzoj4999 This Problem Is Too Simple!
- Typically this problem occurs when you are putting in a data that is too long for the column. In t