Language: C++

#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 300001


int N = 1;
int index,root;
int num_count[NUM][10],change_table[NUM][10];
int LEFT[100000],RIGHT[100000];
vector<int> G[100000];


void init(int first_N){
	while(N < first_N)N *= 2;
}

//最初、全ての電球の明るさは0
void add(int loc){
	loc += N-1;

	num_count[loc][0] += 1;

	while(loc > 0){
		loc = (loc-1)/2;
		num_count[loc][0] = num_count[2*loc+1][0]+num_count[2*loc+2][0];
	}
}

void update(int update_left,int update_right,int node_id,int node_left,int node_right,int x,int y){

	if(update_right < node_left || update_left > node_right)return; //範囲外なら何もしない
	else if(update_left <= node_left && update_right >= node_right){ //このノードのカバー区間が、更新区間の部分区間である場合

		//printf("部分区間 node_id:%d node_left:%d node_right:%d\n",node_id,node_left,node_right);
		for(int i = 0; i <= 9; i++){
			if((change_table[node_id][i] == x) || (i == x && change_table[node_id][i] == -1)){
				change_table[node_id][i] = y; //変換対応を更新
				//printf("%dが%dになる\n",i,y);
				num_count[node_id][y] += num_count[node_id][i];
				num_count[node_id][i] = 0;
			}
		}

		/*for(int i = 0; i <= 9; i++){
			if(num_count[node_id][i] > 0){
				printf("num_count[%d]:%d\n",i,num_count[node_id][i]);
			}
		}*/

		return; //更新は子方向に伝えない

	}else{
		//このノードのカバー範囲と更新範囲に部分的な重なりがある場合
		//現在自分が★蓄積していた(子供に伝えていなかった)★変換情報を子に投げる(★★更新区間が、node_left～node_rightであることに注意★★)

		//printf("一部一致 node_id:%d node_left:%d node_right:%d\n",node_id,node_left,node_right);

		for(int i = 0; i <= 9; i++){

			if(change_table[node_id][i] == -1)continue;
			update(node_left,node_right,2*node_id+1,node_left,(node_left+node_right)/2,i,change_table[node_id][i]);
			update(node_left,node_right,2*node_id+2,(node_left+node_right)/2+1,node_right,i,change_table[node_id][i]);

			change_table[node_id][i] = -1; //更新情報は1度投げれば良し
		}

		//改めて今回のクエリを投げる
		update(update_left,update_right,2*node_id+1,node_left,(node_left+node_right)/2,x,y);
		update(update_left,update_right,2*node_id+2,(node_left+node_right)/2+1,node_right,x,y);

		//★★子にクエリを投げた結果、このノードの以下の集計が変わるので、ボトムアップ的に再帰的に計算する
		for(int i = 0; i <= 9; i++){
			num_count[node_id][i] = num_count[2*node_id+1][i]+num_count[2*node_id+2][i];
		}
	}
}


int getSum(int search_left,int search_right,int node_id,int node_left,int node_right,int x,int y){
	if(search_right < node_left || search_left > node_right){
		return 0;
	}else if(search_left <= node_left && search_right >= node_right){

		int ret = 0;
		for(int i = x; i <= y; i++){
			ret += num_count[node_id][i];
		}

		return ret;

	}else{

		//自分が★蓄積していた(子供に伝えていなかった)★変換情報を子に投げる
		for(int i = 0; i <= 9; i++){

			if(change_table[node_id][i] == -1)continue;
			update(node_left,node_right,2*node_id+1,node_left,(node_left+node_right)/2,i,change_table[node_id][i]);
			update(node_left,node_right,2*node_id+2,(node_left+node_right)/2+1,node_right,i,change_table[node_id][i]);

			change_table[node_id][i] = -1; //更新情報は1度投げれば良し
		}

		int left = getSum(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2,x,y);
		int right = getSum(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right,x,y);
		return left+right;
	}
}


//オイラーツアーで、ノードのカバー範囲を計算する
void euler_tour(int node_id,int pre_node){
	LEFT[node_id] = index++;

	for(int i = 0; i < G[node_id].size(); i++){
		if(G[node_id][i] == pre_node)continue;
		euler_tour(G[node_id][i],node_id);
	}
	RIGHT[node_id] = index++;
}

int main(){

	index = 0;
	root = 0;

	int V,Q;
	scanf("%d %d",&V,&Q);

	int from,to;

	for(int loop = 0; loop < V-1; loop++){
		scanf("%d %d",&from,&to);
		G[from].push_back(to);
		G[to].push_back(from);
	}

	euler_tour(root,-1);

	int first_N = RIGHT[root]+1; //セグ木における最下層のノードは、最低RIGHT[root]+1個あれば良い(+1は0オリジンのため)

	init(first_N);

	//変換配列および集計配列の初期化
	for(int i = 0; i <= 2*N-2; i++){
		for(int k = 0; k <= 9; k++){
			num_count[i][k] = 0;
			change_table[i][k] = -1;
		}
	}

	//有効ノードの個数を、セグメント木に反映させる
	for(int i = 0; i < V; i++){
		add(LEFT[i]);
	}

	/*printf("N:%d\n",N);

	for(int i = 0; i < V; i++){
		printf("LEFT[%d]:%d RIHGT:%d\n",i,LEFT[i],RIGHT[i]);
	}
	for(int i = 0; i <= 2*N-2; i++){
		printf("num_count[%d][0]:%d\n",i,num_count[i][0]);
	}*/

	int command,node_id,x,y;

	for(int loop = 0; loop < Q; loop++){

		scanf("%d %d %d %d",&command,&node_id,&x,&y);

		if(command == 1){ //計上

			printf("%d\n",getSum(LEFT[node_id],RIGHT[node_id],0,0,N-1,x,y));

		}else{ //更新

			/*printf("\nクエリ%d\n",loop);
			printf("LEFT[%d]:%d RIHGT:%d\n",node_id,LEFT[node_id],RIGHT[node_id]);*/

			if(x == y)continue;

			update(LEFT[node_id],RIGHT[node_id],0,0,N-1,x,y);
		}
	}

	return 0;
}



Compiler output:
a.cc:14:5: error: 'int index' redeclared as different kind of entity
   14 | int index,root;
      |     ^~~~~
In file included from /usr/include/string.h:462,
                 from /usr/include/c++/14/cstring:43,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:121,
                 from a.cc:1:
/usr/include/strings.h:50:20: note: previous declaration 'const char* index(const char*, int)'
   50 | extern const char *index (const char *__s, int __c)
      |                    ^~~~~
a.cc: In function 'void euler_tour(int, int)':
a.cc:119:30: error: no post-increment operator for type
  119 |         LEFT[node_id] = index++;
      |                              ^~
a.cc:125:31: error: no post-increment operator for type
  125 |         RIGHT[node_id] = index++;
      |                               ^~
a.cc: In function 'int main()':
a.cc:130:17: error: overloaded function with no contextual type information
  130 |         index = 0;
      |                 ^