Topic Link: Click to open the link
Test instructions: Give you a tree, root node is 1, Q Group operations, each set of operations there are two, one is the value of all sub-tree nodes of a node all +1, and the other is to query a node of the subtree node value%m The remainder of the number of primes.
Idea: For the first operation, we can think of using DFS sequence to re-label the tree, so that a node of the sub-tree node is adjacent to a line segment, so that it can be easily processed with the line segment tree. For the second operation, in order to maintain a value within a range, we can use Bitset as the node information. We can open a M-bit of bitset, for each bit, 1 means this number in this interval, and finally with the Prime table and the answer to the line.
For adding a number to this operation, since we only need the remainder of M, we can consider using a bitwise operation to cycle the shift. s << x means to move the set S left X-bit, equivalent to add each number x, S >> m-x, to the right shift m-x bit, so, both and, is equivalent to the first operation, notice, bitset bits and integers are the same, high in the left, low in the right.
See the code for details:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include < string> #include <vector> #include <stack> #include <bitset> #include <cstdlib> #include < cmath> #include <set> #include <list> #include <deque> #include <map> #include <queue># Define MAX (a) > (b)? ( A):(B) #define MIN (a) < (b) ( A):(B)) using namespace Std;typedef long long ll;typedef long double ld; #define M 1010typedef bitset<m> bt;const ld E PS = 1e-9, PI = 3.1415926535897932384626433832795;const int mod = 1000000000 + 7;const int INF = int (1e9);//& 0X7FFFF fffconst int seed = 131;const ll INF64 = ll (1e18); const int MAXN = 1e5 + 10;int t,n,m,cnt=0,addv[maxn<<2],id[maxn],l AST[MAXN],A[MAXN],B[MAXN],VIS[M];BT sum[maxn<<2], res;void pushup (int o) {Sum[o] = sum[o<<1] | sum[o<&l T;1|1];} void Add (int& a, int b) {A + = B; if (a >= m) A-= m; void Change (BT &x, int y) {x = (x << Y) | (x >> m-y);} void pushdown (int o) {if (Addv[o]) {Add (addv[o<<1], addv[o]); Add (Addv[o<<1|1], addv[o]); Change (sum[o<<1], addv[o]); Change (sum[o<<1|1], addv[o]); Addv[o] = 0; }}void Build (int l, int r, int o) {int m = (L + r) >> 1; Addv[o] = 0; Sum[o].reset (); if (L = = r) {Sum[o][b[l]] = 1; return; } build (L, M, o<<1); Build (M+1, R, O<<1|1); Pushup (o);} void Update (int l, int r, int v, int l, int r, int o) {int m = (L + R) >> 1; if (l <= l && R <= R) {Add (Addv[o], V); Change (Sum[o], V); return; } pushdown (o); if (l <= m) update (L, R, V, L, M, o<<1); if (M < R) Update (L, R, V, M+1, R, O<<1|1); Pushup (o);} BT Query (int l, int r, int l, int r, int o) {int m = (L + R) >> 1; if (l <= l && R <= R) {return sum[o]; } pushdown (o); BT ans; Ans.reset (); if (l <= m) ans |= query (L, R, L, M, o<<1); if (M < r) Ans |= query (L, R, M+1, R, O<<1|1); return ans;} vector<int> g[maxn];void dfs (int u, int fa) {int len = g[u].size (); Id[u] = ++cnt; B[CNT] = A[u]; for (int i=0;i<len;i++) {int v = g[u][i]; if (v! = FA) {dfs (V, u); }} Last[u] = cnt;} void Init () {for (int i=2;i<m;i++) if (!vis[i]) {res[i] = 1; for (int j=i*i;j<m;j+=i) vis[j] = 1; }}int U, V, II, X, Q;int main () {scanf ("%d%d", &n,&m); Init (); for (int i=1;i<=n;i++) scanf ("%d", &a[i]), a[i]%= m; for (int i=1;i<n;i++) {scanf ("%d%d", &u,&v); G[u].push_back (v); G[v].push_back (U); } DFS (1, 1); Build (1, N, 1); scanf ("%d", &q); while (q--) {scanf ("%d%d", &ii,&v); if (ii = = 1) {scanf ("%d", &x); Update (Id[v], last[v], x%m, 1, N, 1); } ELSE {BT cur = query (Id[v], last[v], 1, N, 1); printf ("%d\n", (res & cur). Count ()); }} return 0;}
Manthan, Codefest (G. Yash and Trees (Dfs order + segment tree))