loj2062 [HAOI2016]地图

ref

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, m, q, a[100005], uu, vv, hea[100005], cnt, dfn[100005], loo[100005];
int idx, dui[100005], qwq[100005], siz[100005], ans[100005], blc1, blc2;
int bei[100005], jis[1000005], qaq[2][1005], ovo[100005];
struct Edge{
	int too, nxt, val;
}edge[300005];
struct Node{
	int ll, rr, id, ty, li;
}nd[100005];
void add_edge(int fro, int too){
	edge[++cnt].nxt = hea[fro];
	edge[cnt].too = too;
	hea[fro] = cnt;
}
bool cmp(Node x, Node y){
	if(bei[x.ll]!=bei[y.ll])	return bei[x.ll]<bei[y.ll];
	if(bei[x.ll]&1)	return x.rr<y.rr;
	else	return x.rr>y.rr;
}
void dfs1(int x, int f){
	dfn[x] = loo[x] = ++idx;
	dui[idx] = x;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(t==f)	continue;
		if(!dfn[t]){
			dfs1(t, x);
			loo[x] = min(loo[x], loo[t]);
		}
		else	loo[x] = min(loo[x], dfn[t]);
	}
}
void dfs2(int x){
	qwq[x] = ++idx;
	siz[x] = 1;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(!qwq[t] && loo[t]>=dfn[x]){
			dfs2(t);
			siz[x] += siz[t];
		}
	}
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(!qwq[t] && loo[t]<dfn[x]){
			dfs2(t);
			siz[dui[loo[t]]] += siz[t];
		}
	}
}
void add(int x){
	int p=(x-1)/blc2+1;
	if(jis[x]&1)	qaq[1][p]--, qaq[0][p]++;
	else if(jis[x])	qaq[0][p]--, qaq[1][p]++;
	else	qaq[1][p]++;
	jis[x]++;
}
void dec(int x){
	int p=(x-1)/blc2+1;
	if(jis[x]==1)	qaq[1][p]--;
	else if(jis[x]&1)	qaq[1][p]--, qaq[0][p]++;
	else	qaq[0][p]--, qaq[1][p]++;
	jis[x]--;
}
int main(){
	cin>>n>>m;
	blc1 = sqrt(n);
	blc2 = sqrt(1000000);
	for(int i=1; i<=n; i++){
		scanf("%d", &a[i]);
		bei[i] = (i - 1) / blc1 + 1;
	}
	for(int i=1; i<=m; i++){
		scanf("%d %d", &uu, &vv);
		add_edge(uu, vv);
		add_edge(vv, uu);
	}
	dfs1(1, 0);
	idx = 0;
	dfs2(1);
	cin>>q;
	for(int i=1; i<=q; i++){
		scanf("%d %d %d", &nd[i].ty, &uu, &nd[i].li);
		nd[i].ll = qwq[uu]; nd[i].rr = qwq[uu] + siz[uu] - 1;
		nd[i].id = i;
	}
	sort(nd+1, nd+1+q, cmp);
	for(int i=1; i<=n; i++)
		ovo[qwq[i]] = a[i];
	int l=nd[1].ll, r=l-1;
	for(int i=1; i<=q; i++){
		while(l>nd[i].ll)	add(ovo[--l]);
		while(l<nd[i].ll)	dec(ovo[l++]);
		while(r<nd[i].rr)	add(ovo[++r]);
		while(r>nd[i].rr)	dec(ovo[r--]);
		int now=0, p=(nd[i].li-1)/blc2+1;
		for(int j=1; j<p; j++)
			now += qaq[nd[i].ty][j];
		for(int j=blc2*(p-1)+1; j<=nd[i].li; j++)
			if(jis[j] && (jis[j]&1)==nd[i].ty)
				now++;
		ans[nd[i].id] = now;
	}
	for(int i=1; i<=q; i++)
		printf("%d
", ans[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/9003609.html