树上差分WA on 46求助
  • 板块CF19E Fairy
  • 楼主ppppppjjx
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/3/21 22:08
  • 上次更新2024/3/22 13:15:50
查看原帖
树上差分WA on 46求助
801347
ppppppjjx楼主2024/3/21 22:08
#include<cstdio>
#include<cstring>
#include<random>
#include<ctime>
#define N 10005
int n,m;
int em,e[N<<1],nx[N<<1],ls[N],way[N<<1];
bool used[N<<1];
void insert(int x,int y,int note){
	e[++em]=y;
	nx[em]=ls[x];
	ls[x]=em;
	way[em]=note;
}
bool vis[N];
int dep[N];
int flag;
int fa[N][25],use[N];
struct node{int whe,s;};
node lca(int x,int y){
	int s=0;
	for(int i=20;i>-1;i--){
		if(dep[fa[x][i]]>=dep[y]){
			s+=(1<<i);
			x=fa[x][i];
		}
	}
	for(int i=20;i>-1;i--){
		if(dep[fa[y][i]]>=dep[x]){
			s+=(1<<i);
			y=fa[y][i];
		}
	}
	for(int i=20;i>-1;i--){
		if(fa[x][i]!=fa[y][i]){
			s+=(1<<i);
			x=fa[x][i];
			s+=(1<<i);
			y=fa[y][i];
		}
	}
	if(x!=y)x=fa[x][0],y=fa[y][0],s+=2;
	node u;
	u.s=s;
	u.whe=x;
	return u;
}
int S[N];
node now;
int ans[N];
void dg1(int x,int father){
	dep[x]=dep[father]+1;
	fa[x][0]=father;
	for(int i=1;i<21;i++)
		fa[x][i]=fa[fa[x][i-1]][i-1];
	vis[x]=1;
	for(int i=ls[x];i;i=nx[i]){
		if(vis[e[i]])continue;
		use[e[i]]=way[i];
		used[i]=1;
		dg1(e[i],x);
	}
}
int Ans;
void dg2(int x){
	vis[x]=1;
	for(int i=ls[x];i;i=nx[i]){
		if(!used[i])continue;
		dg2(e[i]);
		S[x]+=S[e[i]];
	}
	if(use[x])
	ans[use[x]]=S[x];
}
bool all[N];
int main(){
	srand(time(0));
	scanf("%d%d",&n,&m);
	for(int i=1,p,q;i<=m;i++){
		scanf("%d%d",&p,&q);
		insert(p,q,i);
		insert(q,p,i);
	}
	for(int i=1;i<=m;i++)
		all[i]=1;
	for(int q=0,p;q<50;q++){//多次调用
		p=rand()%n+1;
		memset(used,0,sizeof used);
		memset(use,0,sizeof use);
		memset(ans,0,sizeof ans);
		memset(vis,0,sizeof vis);
		memset(fa,0,sizeof fa);
		memset(S,0,sizeof S);
		flag=0;
		dep[0]=1;
		for(int i=1,j=p;i<=n;i++,j++){
			if(j>n)j-=n;
			if(!vis[j])
				dg1(j,0);
		}
		for(int i=1;i<=n;i++){
			vis[i]=0;
			for(int j=ls[i];j;j=nx[j]){
				now=lca(i,e[j]);
				if(now.s%2)
					continue;
				flag++;
				S[i]++;
				S[e[j]]++;
				S[now.whe]-=2;
				ans[way[j]]++;
			}
		}
		if(flag==0){
			printf("%d\n",m);
			for(int i=1;i<=m;i++)
				printf("%d ",i);
			return 0;
		}
		for(int i=1,j=p;i<=n;i++,j++){
			if(j>n)j-=n;
			if(!vis[j])
				dg2(j);
		}
		for(int i=1;i<=m;i++)
			if(ans[i]!=flag)
				all[i]=0;
	}
	for(int i=1;i<=m;i++)
		if(all[i])
			Ans++;
	printf("%d\n",Ans);
	for(int i=1;i<=m;i++)
		if(all[i])
			printf("%d ",i);
	return 0;
}
2024/3/21 22:08
加载中...