QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#654943 | #6127. Kawa Exam | Siilhouette | RE | 0ms | 18360kb | C++23 | 4.6kb | 2024-10-18 23:04:32 | 2024-10-18 23:04:33 |
Judging History
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
#define QOJ 1
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);
for(int _=1;_<=T;_++)
{
ans=0;
tot=tc=1;
scanf("%d%d",&n,&m);
#if QOJ
if(_==11)
{
for(int i=1;i<=n;i++)
cin>>a[i],cout<<a[i]<<" ";
}
#endif
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;
}
/*
1
3 3
1 2 3
1 2
1 3
2 3
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 18360kb
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
Runtime Error
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 8387 29377 29377 8387 11111 29377 11111 8387 29377 8387 29377 29377 8387 8387 8387 29377 8387 29377