RT.
希望有人能给我的代码一个 Hack 数据。
::::info[浅述思路。] 根号分治,分开搞。
为了方便,在之后的处理中让 m→m×2。
读入 u 和 v。
令 di 表示 i 的度数。
这种情况下考虑直接暴力,开一个 tmp 数组,首先枚举 u 的所有邻点并打上标记,然后枚举 v 的所有相邻点(以及 v 本身)并累加 tmp 中所有这些位置的值,统计出累加结果 sum,最后输出 du−sum 即可。
这种情况下考虑预处理。由于 d 之和也只有 m,所以满足 du>m 的 u 的个数绝对不会超过 m,因此一开始预处理一下相互的匹配情况即可。 ::::
::::info[上个代码。]
#include<bits/stdc++.h>
#define LL long long
#define UInt unsigned int
#define ULL unsigned long long
#define pii pair<int,int>
#define fr first
#define se second
#define pb push_back
using namespace std;
const int N = 2e5+5 , Sq = 705;
int n,m,Q,d[N],cnt,id[N],ans[N][Sq],tmp[N];
vector<int> g[N];
int min(int x,int y){return (x<y?x:y);}
int max(int x,int y){return (x>y?x:y);}
int read(){
int su=0,pp=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')pp=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){su=su*10+ch-'0';ch=getchar();}
return su*pp;
}
int main(){
n=read(),m=read(),Q=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
d[x]++,d[y]++,g[x].pb(y),g[y].pb(x);
}
m*=2;
for(int i=1;i<=n;i++){
if(d[i]*d[i]<=m)continue;
id[i]=++cnt;
for(int x:g[i])tmp[x]++;
for(int j=1;j<=n;j++){
ans[cnt][j]=tmp[j];
for(int x:g[j])ans[cnt][j]+=tmp[x];
}
for(int x:g[i])tmp[x]--;
}
while(Q--){
int u=read(),v=read();
if(d[u]*d[u]<=m){
for(int x:g[u])tmp[x]++;
int sum=tmp[v];
for(int x:g[v])sum+=tmp[x];
cout<<d[u]-sum<<"\n";
for(int x:g[u])tmp[x]--;
}
else cout<<d[u]-ans[id[u]][v]<<"\n";
}
return 0;
}
::::
具体的细节可能还是去我的代码里看会比较清晰。代码没有特意压行,应该还是比较可观的吧。
主要的话就是想要一个可以把我成功 Hack 死的数据,然后我就可以自己去调试了。要求这个数据的 n 不要超过 10,m 不超过 20。对数据的大小限制主要是方便我手摇。
不介意使用题解的代码与我的代码对拍以获得 Hack 数据。
如果有人能直接指出代码中的逻辑错误那肯定更好!
都玄关。
蟹蟹喵!
记得 at 我哦 /kel