首页 > 代码库 > BJOI2014 想法
BJOI2014 想法
3765. 【BJOI2014】想法 (Standard IO)
Time Limits: 4000 ms Memory Limits: 262144 KB Special Judge
60分直接压位即可
接下来说说满分的神级做法:
随机大法!
对于每个想法Random一个随机器代表它,合并的时候保留前T小的数。最后的答案即是T*RAND_MAX/(第T小的数)
为什么这样可以呢?
设包含的总想法数为L,在L中取到T的期望为T/L,而随机数是均匀分布的,所以T/L会等于RAND_T/RAND_MAX,所以L=T*RAND_MAX/RAND_T
#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>#include<cstring>#include<ctime>using namespace std;double r;int son[1000111][2];int a[1001111][31];int tt,n,m,T,tl,mx,i,x,z,seed,t,lim;double ans[1000111];void cger(int *a,int *b,int *c){ int j,k,i,al,bl; al=1; bl=1; c[0]=0; while(al<=a[0]&&bl<=b[0]){ if(a[al]<b[bl]){ if(a[al]!=c[c[0]]){ c[0]++; c[c[0]]=a[al]; } al++; } else{ if(b[bl]!=c[c[0]]){ c[0]++; c[c[0]]=b[bl]; } bl++; } if(c[0]==lim)break; } if(c[0]!=lim){ while(al<=a[0]){ if(a[al]!=c[c[0]]){ c[0]++; c[c[0]]=a[al]; } al++; if(c[0]==lim)break; } while(bl<=b[0]){ if(b[bl]!=c[c[0]]){ c[0]++; c[c[0]]=b[bl]; } bl++; if(c[0]==lim)break; } }}int main(){ srand((unsigned)time(0)); seed=1; scanf("%d%d",&n,&m); lim=20; for(i=m+1;i<=n;i++){ scanf("%d%d",&x,&z); son[i][0]=x; son[i][1]=z; } T=10000000/n; for(tl=1;tl<=T;tl++){ mx=0; for(i=1;i<=m;i++){ a[i][1]=rand()+1; a[i][0]=1; } for(i=m+1;i<=n;i++)a[i][0]=0; for(i=m+1;i<=n;i++){ cger(a[son[i][0]],a[son[i][1]],a[i]); if(a[i][0]<lim)ans[i]+=a[i][0]; else ans[i]=ans[i]+(double)lim*(double)RAND_MAX/(double)a[i][a[i][0]]; } } for(i=m+1;i<=n;i++){ t=(int)(ans[i]/(double)T+0.001); printf("%d\n",t); }}
BJOI2014 想法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。