Test instructions: Given a structure with a root tree and the color of each point at the beginning, there are two actions 1: coloring the subtree of a given point 2: How many colors are in the subtree of the given point
It's easier to think of Dfs sequence + line tree to do
DFS sequence is a long time ago to see the Bilibili on the video of the study of a tree through the DFS number to the number of each point of the sub-tree to join together as a contiguous interval can be associated with the sub-tree line tree
Because it seems to have heard that the line segment tree can solve a range of changes and query interval of different XX number ... So suddenly I thought of ...
But I don't write line-segment trees. Only the simplest single-point modification interval query ... Do not use delay tags ... So take out the book now learn a pitch.
Ask seniors how to record different color number seniors on the wit told me to use Longlong to engage.
Although I know the idea. Or wrote more than a day.
The DFS sequence makes the numbering of each point and records the left and right intervals of the subtree for each point
The initial Crea is assigned and pushup
Use Longlong's 64-bit to have what color to use or to do the transfer
1l<<50 what seems to have shifted the left too much to shoot. To define an L variable outside: Cry..
Write line segment tree so tired ... (The face is full of tears) ... But Peach's little pink is very comfortable to knock up ...
#include <stdio.h> #include <string.h> #include <algorithm> #include <map> #include <math.h > #include <iostream> #include <queue> #include <string>using namespace std; #define L long longint N, m; struct node{int l,r; L Ma;}; int A[400050];node tree[400050*8];vector<int >q[400050];int id[400050]; L mark[400050*8];int cnt; struct no{int l,r;}; No zg[400050];int fx[400050];void dfs (int u) {id[u] = ++cnt; FX[CNT] = u; ZG[U].L = CNT; for (int i=0;i<q[u].size (); i++) {int v = q[u][i]; if (id[v] = =-1) {DFS (v); }} ZG[U].R = cnt;} void pushup (int root) {tree[root].ma = Tree[root*2].ma | tree[root*2+1].ma;} void pushdown (int root) {if (Mark[root]! =-1) {mark[root*2] = mark[root*2+1] = Mark[root]; Tree[root].ma = Mark[root]; tree[root*2].ma = Tree[root*2+1].ma = Mark[root]; Mark[root] =-1; }}void Crea (int root, int l,int r) {tree[root].l = l; TREE[ROOT].R =R if (L = = r) {L res = 1; Res <<= A[fx[l]]; Tree[root].ma = (res); return; } int m = (L + r) >> 1; Crea (root*2,l,m); Crea (root*2+1,m+1,r); Pushup (root);} void upda (int root, int l, int r, int c) {if (TREE[ROOT].R < L | | tree[root].l > R) {return; } if (TREE[ROOT].R <= r && tree[root].l >= L) {L res = 1; Res <<= C; Mark[root] = (res); Pushdown (root); return; } pushdown (root); UPDA (ROOT*2,L,R,C); UPDA (ROOT*2+1,L,R,C); Pushup (root);} L query (int root, int l, int r) {pushdown (root); if (TREE[ROOT].R < L | | tree[root].l > R) {return 0; } if (TREE[ROOT].R <= r && tree[root].l >= l) {return tree[root].ma; } L ans = 0; Ans |= query (root*2,l,r); Ans |= query (root*2+1,l,r); Pushup (root); return ans;} int main () {scanf ("%d%d", &n,&m); for (int i=1;i<=n;i++) {scanf ("%d", &a[i]); Q[i].clear (); } cnt = 0; Memset (id,-1,sizeof (id)); for (int i=1;i<=n-1;i++) {int u,v; scanf ("%d%d", &u,&v); Q[v].push_back (U); Q[u].push_back (v); } memset (Mark,-1,sizeof (Mark)); DFS (1); Crea (1,1,cnt); for (int i=1;i<=m;i++) {int k; scanf ("%d", &k); if (k = = 1) {int v,c; scanf ("%d%d", &v,&c); int LL = ZG[V].L; int rr = ZG[V].R; UPDA (1,LL,RR,C); } else {int v; scanf ("%d", &v); int LL = ZG[V].L; int rr = ZG[V].R; L res = query (1,LL,RR); int ans = 0; while (Res > 0) {ans + = (res%2); Res >>= 1; } printf ("%d\n", ans); } }}
Educational codeforces Round 6 E DFS sequence + segment tree