HDU 4358 Boring counting (tree array)
Question :??
Given a tree, each node has a vertex permission, and then there are some queries to find the number of Subtrees with a vertex as the root occurs exactly k times.
Ideas:
First, dfs converts the tree structure into a linear structure at a time, and uses the time stamp to record the start position and end position of the subtree rooted in node u in the array.
In this case, all query records are recorded offline and all queries are sorted in ascending order on the right endpoint.
Consider using a tree array to solve this problem. Each location record appears exactly k times from 1 to the current location.
Traverse the array from the beginning, and map the location where each value appears. For each position, if the number of times t appears is greater than k, then add one at the location where the t-k appears, and subtract two from the location where the t-k-1 appears. If the current location is the same as the r of a query, record the answer sum (r) -sum L-1)
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define eps 1e-6 # define LL long # define pii (pair
) # Pragma comment (linker,/STACK: 1024000000,1024000000) using namespace std; const int maxn = 100000 + 50; // const int INF = 0x3f3f3f; int n, k, q, clock_cnt, dis, kase; int w [maxn], tim [maxn] [2], a [maxn]; vector
G [maxn]; int vis [maxn], ans [maxn], cnt [maxn]; vector
Pos [maxn]; map
Trans; int C [maxn]; int lowbit (int x) {return (x & (-x);} int sumv (int x) {int ret = 0; while (x> 0) {ret + = C [x]; x-= lowbit (x);} return ret;} void add (int x, int d) {while (x <= n) {C [x] + = d; x + = lowbit (x) ;}} void init () {for (int I = 1; I <= n; I ++) {G [I]. clear (); pos [I]. clear ();} trans. clear (); clock_cnt = 0; dis = 0; // discretization memset (cnt, 0, sizeof (cnt); memset (tim, 0, sizeof (tim )); memset (vis, 0, sizeof (vi S); memset (C, 0, sizeof (C);} int Hash (int t) {if (! Trans. count (t) return trans [t] = ++ dis; return trans [t];} void dfs (int u) {tim [u] [0] = ++ clock_cnt; a [clock_cnt] = w [u]; vis [u] = 1; int sz = G [u]. size (); for (int I = 0; I <sz; I ++) {int v = G [u] [I]; if (vis [v]) continue; dfs (v);} tim [u] [1] = clock_cnt;} struct Query {int l, r, id; bool operator <(const Query) const {return r <. r ;}} query [maxn]; void solve () {if (kase) cout <endl; printf (Case # % d:, ++ kase ); int cur = 0; for (int I = 1; I <= n; I ++) {cnt [Hash (a [I])] ++; pos [Hash (a [I])]. push_back (I); if (cnt [Hash (a [I])]> = k) {add (pos [Hash (a [I])] [cnt [Hash (a [I])]-k], 1); if (cnt [Hash (a [I])]> k) add (pos [Hash (a [I])] [cnt [Hash (a [I])]-k-1],-2 );} while (cur <q & query [cur]. r = I) {ans [query [cur]. id] = sumv (query [cur]. r)-sumv (query [cur]. l-1); cur ++ ;}}for (int I = 0; I <q; I ++) printf (% d, ans [I]); // cout <dis <endl; // for (int I = 1; I <= dis; I ++) cout <cnt [I] <endl ;} int main () {// freopen(input.txt, r, stdin); int T; cin> T; while (T --) {init (); scanf (% d, & n, & k); for (int I = 1; I <= n; I ++) scanf (% d, & w [I]); for (int I = 0; I
> Q; for (int I = 0; I <q; I ++) {int t; scanf (% d, & t); query [I]. l = tim [t] [0]; query [I]. r = tim [t] [1]; query [I]. id = I;} sort (query, query + q); // for (int I = 0; I <q; I ++) cout <query [I]. l <query [I]. r <endl; // cout <clock_cnt <endl; // for (int I = 1; I <= clock_cnt; I ++) cout <a [I] <endl; solve ();} return 0 ;}