【NOI2017模拟3.30】轮回(根号算法,暴力)
2017-03-31 09:46
393 查看
Description
掌管着世界的暗流的是一个叫做Samjia的人。他看到所有人的生死,他看见所有人一世又一世的轮回,而他却从未把握过自己的命。
在无法估计的命中,他看见那些轮回,他很好奇,这一切的一切,都是如何开始如何结束,他想,就算是他也会堕入这样的轮回中的吧。
于是他开始数轮回,他看到的是一个有n个点m条边的无向图(边是带标号的),一个轮回是一个由四条边组成的环,环中不能有重复的边,除了起点和终点外(当然,由于是一个环,起点和终点是一样的)不能经过一个同样的点多次。两个轮回被视为不同的当且仅当两个轮回各自的4条边中有一条的编号不同,Samjia想知道,这个system中有多少不同的轮回。
他忙着思考人生,所以数轮回的任务就交给你了。
Solution
比赛的时候直接打了个很稳定的暴力,但是因为数据水,那些打不稳定的暴力都过了。这题有一个很高级的思路:如果枚举与一个点相邻且度数大于等于它的点,复杂度数O(m−−√)的
证明:如果设点i,与它相邻且度数比它大的点有x个,那么假设这些点每个点与它相邻的边都有x个,所以x∗x≤2∗m=>x≤2∗m−−−−−√,那么枚举的复杂度就是O(x)≤O(2∗m−−−−−√)。
那么这道题就枚举一个点i,然后枚举度数比它大的点j,然后在枚举j连出去的点且都数比它大的点k,然后得出到k的方案数num,对答案贡献(num-1)*num/2。
i和j的复杂度是O(nm−−√),k的总复杂度是2*m的。
但是还有一个小细节,就是如果对于度数相等的情况,如果直接求可能会算重,所以就要搞出优先级,那么直接把度数排一个序就好了。
Code
#include<iostream> #include<stdio.h> #include<algorithm> #include<math.h> #include<string.h> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) #define rep(i,a) for(i=first[a];i;i=next[i]) const int maxn=1e5+7; typedef long long ll; using namespace std; int first[maxn*2],last[maxn*2],next[maxn*2],a[maxn],num; int i,j,k,l,n,m,du[maxn*2],c[maxn],az[maxn],tot,you[maxn],b[maxn]; ll ans,t; bool bz[maxn]; void add(int x,int y){ last[++num]=y,next[num]=first[x],first[x]=num; } int main(){ freopen("palingenesis.in","r",stdin); freopen("palingenesis.out","w",stdout); // freopen("fan.in","r",stdin); // freopen("fan.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,m){ scanf("%d%d",&k,&l);du[k]++,du[l]++; add(k,l),add(l,k); } fo(i,1,n)b[du[i]]++;fo(i,1,n)b[i]+=b[i-1]; fod(i,n,1)you[i]=b[du[i]]--; fo(i,1,n){ tot=0; rep(j,i){ if(you[last[j]]>you[i]){ rep(k,last[j]){ if(you[last[k]]<you[i])continue; if(last[k]==i)continue; if(!bz[last[k]]){ az[last[k]]=++tot; bz[last[k]]=1; } a[az[last[k]]]++; } } } fo(j,1,tot)ans+=a[j]*(a[j]-1)/2,a[j]=0; rep(j,i){ if(you[last[j]]>=you[i]){ rep(k,last[j]){ if(last[k]==i)continue; bz[last[k]]=0; az[last[k]]=0; } } } } printf("%lld\n",ans); }
相关文章推荐
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- [JZOJ5037]【NOI2017模拟3.30】轮回
- JZOI【NOI2017模拟3.30】轮回
- JZOJ【NOI2017模拟3.30】原谅
- zzu 10480: 回文串 -- 模拟(最怕这种表面是算法,实际暴力的坑题)
- 【JZOJ5036】【NOI2017模拟3.30】原谅
- [JZOJ5036]【NOI2017模拟3.30】原谅
- 【NOI2017模拟3.30】原谅(计算几何,期望)
- 【NOI2017模拟3.30】原谅
- BZOJ - 4810 [Ynoi2017]由乃的玉米田 莫队算法 + bitset 大暴力
- JZOJ4744. 【NOIP2016提高A组模拟9.2】同余 一类比较好的分类思想+根号算法
- 【JZOJ100005】【NOI2017模拟.4.1】Shoes
- 【java-算法】【华为真题】老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.
- 对于简单模拟路由寻路算法代码的学习。
- 【算法学习笔记】16.暴力求解法04 回溯法03 剪枝法 带宽
- ssdb底层实现——ssdb底层是leveldb,leveldb根本上是skiplist(例如为存储多个list items,必然有多个item key,而非暴力string cat),用它来做redis的list和set等,势必在数据结构和算法层面上有诸多不适
- 相机中白平衡的算法模拟实现
- 基本算法——第一单元 模拟
- NOIP模拟 NYG的背包 [高山算法]