您的位置:首页 > 其它

NOIP模拟(20171030)T3 星星

2017-11-01 08:48 281 查看
题意:(说不清)

一道证明复杂度题

这样是O(mm−−√log2n) 的

自己看吧~

#include<bits/stdc++.h>
#define LEN 300000
using namespace std;
inline int getint(){
int x=0,p=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')p=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<3)+(x<<1)+(c^'0');
c=getchar();
}
return x*p;
}
struct road{
int u,v;
}r[LEN];
vector<int>r2[LEN];
int d[LEN];
inline void work(){
int n=getint(),m=getint();
for(int i=0;i<=n+1;++i){
r2[i].clear();
d[i]=0;
}
for(int i=0;i<=m+1;++i){
r[i].u=r[i].v=0;
}
#if n==30
#define int char
#endif
for(int i=1;i<=m;++i){
int u=getint(),v=getint();
r[i].u=u,r[i].v=v;
r2[u].push_back(v);
r2[v].push_back(u);
++d[u],++d[v];
}
for(int i=1;i<=n;++i){
sort(r2[i].begin(),r2[i].end());
}
long long ans=0;
for(int i=1;i<=m;++i){
int u=r[i].u,v=r[i].v;
if(d[u]>d[v])swap(u,v);
int tot=0;
vector<int>::iterator xx=r2[v].begin();
for(int j=0;j<d[u];++j){
if((xx=lower_bound(xx,r2[v].end(),r2[u][j]))!=r2[v].end()&&*xx==r2[u][j]){
++tot;
}
if(xx==r2[v].end())break;
}
ans+=(long long)tot*(tot-1)/2;
}
cout<<ans<<"\n";
}
int main(){
int t=getint();
while(t--){
work();
}
return 0;
}


好吧,证一下复杂度。

将点分为两类,度数<n√的叫轻点,反之叫重点

易得重点不超过O(n√)个

对于所有有至少一端为轻点的边,每次查询复杂度为O(n√log2n)的

对于所有连接两个重点的边,我们考虑每个黑点被作为代码中的v 的时后,最多会枚举所有度数比它小的所有点的所有边,总边数不超过m,共O(n√)个黑点,故总复杂度为O(n√log2n)

证毕
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: