QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#654905#6127. Kawa ExamSiilhouetteWA 409ms32576kbC++234.4kb2024-10-18 22:49:012024-10-18 22:49:02

Judging History

你现在查看的是最新测评结果

  • [2024-10-18 22:49:02]
  • 评测
  • 测评结果:WA
  • 用时:409ms
  • 内存:32576kb
  • [2024-10-18 22:49:01]
  • 提交

answer

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<map>
using namespace std;

const int N=200010;
int head[N],ver[N<<1],suiv[N<<1],dfn[N],low[N],c[N],vis[N],cnt[N],siz[N],son[N],edge[N<<1],eans[N<<1];
int n,m,tot,num,dcc,ans,a[N];
bool pont[N];
int hc[N],vc[N<<1],sc[N<<1],ec[N<<1],tc;
vector<int>inc[N];

#define DEBUG 0

inline void add_c(int x,int y,int z)
{
#if DEBUG
	cout<<"add_c "<<x<<" "<<y<<" "<<z<<endl;
#endif
	vc[++tc]=y;
	ec[tc]=z;
	sc[tc]=hc[x];
	hc[x]=tc;
}

inline void add(int x,int y,int z)  //edge存的是边的编号
{
	ver[++tot]=y;
	edge[tot]=z;
	suiv[tot]=head[x];
	head[x]=tot;
}

inline void tarjan_pont(int x,int inedge)
{
	dfn[x]=low[x]=++num;
	for(int i=head[x];i;i=suiv[i])
	{
		int y=ver[i];
		if(!dfn[y])
		{
			tarjan_pont(y,i);
			low[x]=min(low[x],low[y]);
			if(low[y]>dfn[x])
				pont[i]=pont[i^1]=1;
		}
		else if(i!=(inedge^1))
			low[x]=min(low[x],dfn[y]);
	}
}

inline void dfs_eDCC(int x)
{
	c[x]=dcc;
	inc[dcc].push_back(a[x]);
	for(int i=head[x];i;i=suiv[i])
	{
		int y=ver[i];
		if(c[y] || pont[i])continue;
		dfs_eDCC(y);
	}
}

inline void init(int x)
{
	for(int i=1;i<=x;i++)
		head[i]=hc[i]=dfn[i]=low[i]=c[i]=vis[i]=cnt[i]=siz[i]=son[i]=0,
		inc[i].clear();
	for(int i=1;i<=tot;i++)
		pont[i]=0;
	tot=tc=1;
	num=dcc=ans=0;
}

struct Barrel{  //计算众数个数
	int maxi,b[N],cntb[N];
	Barrel(){maxi=0;}
	inline void insert(int x)
	{
		if(b[x])cntb[b[x]]--;
		b[x]++;
		cntb[b[x]]++;
		if(b[x]>maxi)maxi=b[x];
	}

	inline void del(int x)
	{
		cntb[b[x]]--;
		b[x]--;
		if(b[x])cntb[b[x]]++;
		while(!cntb[maxi]&&maxi)maxi--;
	}

	inline int getnum(){return maxi;}

}t1,t2;

//缩点后的siz应该是 真实的点数 因为DSUon tree的时候需要遍历所有的点 
inline void dfs1(int x,int& maxi,int fa=-1,int maxison=-1)  
{
	vis[x]=1;siz[x]=inc[x].size();
	for(auto pos:inc[x])
		t1.insert(pos);
	maxi=max(maxi,t1.getnum());
	for(int i=hc[x];i;i=sc[i])
	{
		int y=vc[i];
		if(y==fa)continue;
		dfs1(y,maxi,x);siz[x]+=siz[y];
		if(siz[y]>maxison)
			maxison=siz[y],son[x]=y;
	}
	for(auto pos:inc[x])
		t1.del(pos);
}

//将这个数里的所有点放入桶 / 从桶里拿出来
inline void dfs2(int x,int val,int fa=-1)
{
	for(auto pos:inc[x])
	{
		if(val==1)t1.insert(pos);
		else t1.del(pos);
	}	
	for(int i=hc[x];i;i=sc[i])
	{
		int y=vc[i];
		if(y==fa)continue;
		dfs2(y,val,x);
	}
}

inline void change(int x,int forbid,int fa,int val)
{
	if(val==1)
		for(auto pos:inc[x])
			t1.del(pos),t2.insert(pos);
	else 
		for(auto pos:inc[x])
			t1.insert(pos),t2.del(pos);
	for(int i=hc[x];i;i=sc[i])
	{
		int y=vc[i];
		if(y==forbid||y==fa)continue;
		change(y,forbid,x,val);
	}
}

inline void dfs3(int x,int fa_edge,int fa,int op=0)
{
	vis[x]=0;
	int son_edge=-1;
	for(int i=hc[x];i;i=sc[i])
	{
		int y=vc[i];
		if(y==son[x])son_edge=i;
		if(y==son[x]||y==fa)continue;
		dfs3(y,i,x);
	}
	if(son[x])dfs3(son[x],son_edge,x,1);
	change(x,son[x],fa,1);
	if(fa_edge!=-1)
	{
#if DEBUG
		cout<<"dfs3 "<<x<<" "<<ec[fa_edge]<<" "<<ans<<" "<<t1.getnum()<<" "<<t2.getnum()<<endl;
#endif
		eans[ec[fa_edge]]=ans+t1.getnum()+t2.getnum();
	}
	if(!op)change(x,0,fa,-1);
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		ans=0;
		tot=tc=1;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		for(int i=1,x,y;i<=m;i++)
		{
			scanf("%d%d",&x,&y);
			add(x,y,i),add(y,x,i);
		}
		for(int i=1;i<=n;i++)
			if(!dfn[i])tarjan_pont(i,0);
		for(int i=1;i<=n;i++)
			if(!c[i])dcc++,dfs_eDCC(i);
		for(int i=2;i<=tot;i++)
		{
			int x=ver[i],y=ver[i^1];
			if(c[x]==c[y])continue;
			add_c(c[x],c[y],edge[i]);
		}	
		for(int i=1;i<=dcc;i++)
		{
			if(vis[i])continue;
#if DEBUG
			cout<<"i "<<i<<" "<<cnt[i]<<endl;
			cout<<"t "<<t1.getnum()<<" "<<t2.getnum()<<endl;
#endif
			dfs1(i,cnt[i]);
			ans+=cnt[i];
#if DEBUG
			cout<<"i "<<i<<" "<<cnt[i]<<endl;
#endif
		}
		for(int i=1;i<=m;i++)
			eans[i]=-1;
		for(int i=1;i<=dcc;i++)
		{
			if(!vis[i])continue;

			ans-=cnt[i];
			dfs2(i,1);
			dfs3(i,-1,-1);
			ans+=cnt[i];
			dfs2(i,-1);
		}
		for(int i=1;i<=m;i++)
		{
			if(eans[i]!=-1)printf("%d",eans[i]);
			else printf("%d",ans);
			if(i<m)putchar(' ');
		}
		putchar('\n');
		init(n);
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 22436kb

input:

3
7 5
1 2 1 2 1 2 1
1 2
1 3
2 4
5 6
5 7
3 3
1 2 3
1 2
1 3
2 3
2 3
12345 54321
1 2
1 2
1 1

output:

6 5 5 5 4
1 1 1
1 1 1

result:

ok 3 lines

Test #2:

score: -100
Wrong Answer
time: 409ms
memory: 32576kb

input:

5557
2 7
79960 79960
2 2
1 1
1 1
2 2
1 1
2 1
1 2
9 8
21881 70740 70740 21881 22458 22458 639 21881 70740
3 3
1 6
5 8
7 5
5 7
2 3
5 1
7 6
6 7
13064 20716 6746 13064 6746 69225
5 5
4 1
4 1
1 6
4 5
3 2
3 2
8 4
45146 14400 45146 45146 14400 72969 14400 45146
8 6
1 3
4 6
8 3
18 13
48132 37949 92338 92338...

output:

2 2 2 2 2 2 2
6 6 7 6 6 6 6 6
3 3 3 4 4 3 3
7 7 7 7
9 9 9 8 9 8 9 8 9 9 10 9 9
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
7 8
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
9 10 9
15 16 16 15 15 16 15 15
10 10 11 10 12 11 10 10 10 10 10 10 10 12 10 10 10 10 10 11
10 8 8 8 9 9 8 8 8 8 9 9 9 8 9 9...

result:

wrong answer 11th lines differ - expected: '16 16 16 16 16 17 16 16', found: '15 16 16 15 15 16 15 15'