百折不挠|

Xdik

园龄:1个月粉丝:7关注:24

[HAOI2016] 地图

仙人掌,所以先建一颗圆方树,这里使用广义圆方树就可以了,然后题目就变成了查询子树内点权 x 且出现了奇数/偶数次的个数,莫队或者线段树合并或者dsu ont tree 都可以

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#pragma GCC optimeze(3)
#pragma GCC optimeze(2)
#define PII pair<int, int>
#define pb push_back
#define fi first
#define se second
#define lowbit(x) (x & (-x))
#define inv(x) (qpow(x,mod-2))
#define blong(i) ((i+K-1)/K)
using namespace std;
const int N=1e6+10;
const int K=1e3+5;
double eps=1e-6;
inline int read(){
	char ch=getchar();bool f=0;int x=0;
	for(;!isdigit(ch);ch=getchar())if(ch=='-')f=1;
	for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
	if(f==1)x=-x;return x;
}
struct que{
	int l,r,x,opt,id;
}qu[N];
int n,m,a[N],dfc,dfn[N],low[N],V,L[N],R[N],rk[N],blong[K*K],q,b[2][K],bj[K*K],ans[N];
stack<int>S;
vector<int>G[N],G2[N];
void tj(int t){
	dfn[t]=low[t]=++dfc;
	S.push(t);
	for(auto to:G[t]){
		if(!dfn[to]){
			tj(to);
			low[t]=min(low[t],low[to]);
			if(low[to]==dfn[t]){
				V++;
				G2[V].pb(t),G2[t].pb(V);
				while(S.top()!=to){
					int x=S.top();S.pop();
					G2[x].pb(V),G2[V].pb(x);
				}	
				int x=S.top();S.pop();
				G2[x].pb(V),G2[V].pb(x);	
			}
		}
		else low[t]=min(low[t],dfn[to]);
	}
}
void dfs(int t,int fa){
	L[t]=++dfc,rk[dfc]=t;
	for(auto to:G2[t]){
		if(to==fa)continue;
		dfs(to,t);
	}
	R[t]=dfc;
}
bool cmp(que a,que b){
	if(blong(a.l)!=blong(b.l))return blong(a.l)<blong(b.l);
	else return (blong(a.l)&1? a.r<b.r:a.r>b.r); 
}
void add(int x){
	if(rk[x]>n)return;
	x=a[rk[x]];
	if(bj[x])b[bj[x]&1][blong(x)]--;
	bj[x]++;
	b[bj[x]&1][blong(x)]++;
}
void del(int x){
	if(rk[x]>n)return;
	x=a[rk[x]];
	b[bj[x]&1][blong(x)]--;
	bj[x]--;
	if(bj[x])b[bj[x]&1][blong(x)]++;
}
int query(int opt,int x){
	int ans=0;
	for(int i=1;i<blong(x);i++)ans+=b[opt][i];
	for(int i=(blong(x)-1)*K+1;i<=x;i++)ans+=((bj[i]&1)==opt&&bj[i]);
	return ans;
}
signed main(){ 
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	srand(time(0));
	cin>>n>>m;
	V=n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=m;i++){
		int u,v;cin>>u>>v;
		G[u].pb(v),G[v].pb(u);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])tj(i);
	}
	dfs(1,0);
	int q;cin>>q;
	for(int i=1;i<=q;i++){
		int t;
		cin>>qu[i].opt>>t>>qu[i].x;
		qu[i].id=i,qu[i].l=L[t],qu[i].r=R[t];
	}
	sort(qu+1,qu+1+q,cmp);
	int l=1,r=0;
	for(int i=1;i<=q;i++){
		while(l>qu[i].l)add(--l);
		while(r<qu[i].r)add(++r);
		while(l<qu[i].l)del(l++);
		while(r>qu[i].r)del(r--);
		ans[qu[i].id]=query(qu[i].opt,qu[i].x);
	}
	for(int i=1;i<=q;i++)cout<<ans[i]<<'\n';
	return 0;
}

本文作者:Xdik

本文链接:https://www.cnblogs.com/Xdik/p/18710134

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Xdik  阅读(5)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起