zoukankan      html  css  js  c++  java
  • [考试反思]0117省选模拟10:争夺

    T3出了一点锅,于是按IOI赛制打的。

    可能也是这辈子唯一一次好好打的IOI赛制了。

    提答,又沉里面了,进去就出不来。莫名的虚荣让我根本没有回头看传统题。

    于是的确在T3的80%时间里一直单题rk1,然而其实很慌,剩下两道题又怎样?

    运气好,T1特别水,T2数据水,T3用奇技淫巧多拿7分于是并列rk1了。

    数组没清空丢了1分。。。

    状态差的不行,一下午一道题都没改出来。。。咕到第二天也没改出来

    于是在第二天考试的时候写完三个暴力之后终于把T2A了。。。

    然后第二天考试就炸了,没什么好说的

    T1:食物链

    大意:就生物上那个。数条数。$n le 100000,mle 200000$

    当成生物题做就行。拓扑。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 200005
     4 int in[S],out[S],deg[S],l[S],fir[S],to[S],ec,n,m,q[S],t;long long dp[S],ans;
     5 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;in[b]++;out[a]++;}
     6 int main(){
     7     scanf("%d%d",&n,&m);
     8     for(int i=1,a,b;i<=m;++i)scanf("%d%d",&a,&b),link(a,b);
     9     for(int i=1;i<=n;++i)if(!in[i])q[++t]=i,dp[i]=1;else deg[i]=in[i];
    10     for(int h=1;h<=t;++h)for(int i=fir[q[h]];i;i=l[i]){
    11         dp[to[i]]+=dp[q[h]];deg[to[i]]--;
    12         if(!deg[to[i]])q[++t]=to[i];
    13     }
    14     for(int i=1;i<=n;++i)if(in[i]&&!out[i])ans+=dp[i];
    15     cout<<ans<<endl;
    16 }
    View Code

    T2:选点游戏

    大意:支持连边,询问某个联通块中最大独立集。点权为1。保证最后是个树。$nle 200000,mle 800000$

    维护子树信息的$LCT$。每个$splay$根维护的是一条实链,开四个变量维护这条链的顶端和底端分别选或不选的最优值。

    比$ddp$和正解都要好理解,好写一些。。。但是常数巨大。

    有一点小的分类讨论,其实代码非常好写。。。$1.6k$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int S=200005,inf=20040124;
     4 int c[2][S],f[S],s[S],lz[S],dp0[S],dp1[S];
     5 #define lc c[0][p]
     6 #define rc c[1][p]
     7 int Max(int a,int b,int c){return max(max(a,b),c);}
     8 struct V{
     9     int __,_$,$_,$$;
    10     V(int a=0,int b=0,int c=0,int d=0){__=a,_$=b;$_=c;$$=d;}
    11     int val(){return Max(max(__,$_),_$,$$);}
    12     V operator+(V x){return V(Max(__+x.__,__+x.$_,_$+x.__),Max(__+x._$,__+x.$$,_$+x._$),Max($_+x.__,$_+x.$_,$$+x.__),Max($_+x._$,$$+x._$,$_+x.$$));}
    13 }v[S];
    14 bool nr(int p){return c[0][f[p]]==p||c[1][f[p]]==p;}
    15 void rev(int p){lz[p]^=1,swap(lc,rc),swap(v[p].$_,v[p]._$);}
    16 void up(int p){v[p]=V(dp0[p],-inf,-inf,dp1[p]+1);if(lc)v[p]=v[lc]+v[p];if(rc)v[p]=v[p]+v[rc];}
    17 void down(int p){if(lz[p])rev(lc),rev(rc),lz[p]=0;}
    18 void spin(int p){
    19     int F=f[p],G=f[F],D=c[1][F]==p,B=c[!D][p];
    20     if(nr(F))c[c[1][G]==F][G]=p; c[!D][p]=F; c[D][F]=B;
    21     if(B)f[B]=F; f[f[F]=p]=G; up(F);
    22 }
    23 void splay(int p){
    24     int tp=1,y=p,F;s[1]=p;
    25     while(nr(y))s[++tp]=y=f[y]; while(tp)down(s[tp--]);
    26     for(;F=f[p],nr(p);spin(p))if(nr(F))spin(c[1][F]==p^c[1][f[F]]==F?p:F); up(p);
    27 }
    28 void asas(int r){
    29     for(int y=0,p=r;p;p=f[y=p]){
    30         splay(p);
    31         dp0[p]+=v[rc].val()-v[y].val();
    32         dp1[p]+=max(v[rc].__,v[rc]._$)-max(v[y].__,v[y]._$);
    33         rc=y,up(p);
    34     }splay(r);
    35 }
    36 void make(int p){asas(p);rev(p);}
    37 void link(int x,int y){make(x);make(y);f[x]=y;dp0[y]+=v[x].val();dp1[y]+=max(v[x].__,v[x]._$);}
    38 int main(){//freopen("1.in","r",stdin);
    39     int n,m;cin>>n>>m;while(m-->0){
    40         int opt,x,y;scanf("%d",&opt);
    41         if(opt)scanf("%d%d",&x,&y),link(x,y);
    42         else scanf("%d",&x),make(x),printf("%d
    ",v[x].val());
    43     }
    44 }
    View Code

    T3:随机

    大意:看代码求输出的期望。

    $Test1:$随机返回$[1,n]$的随机数。

    $frac{1+n}{2}$

    1 #include<bits/stdc++.h>
    2 using namespace std;
    3 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
    4 int main(){
    5     freopen("random1.out","w",stdout);
    6     for(int i=0;i<10;++i)printf("%.10Lf
    ",(1.0L+data[i])/2);
    7 }
    View Code

    $Test2:$$n$个$[1,1000000]$的随机变量的最小值。

    《地震后的幻想乡》的结论,$n$个随机$[0,1]$变量的最小值期望是$frac{1}{n+1}$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
     4 int main(){
     5     freopen("random2.out","w",stdout);
     6     for(int i=0;i<10;++i){
     7         __float128 ans=0;
     8         for(int x=1;x<=1000000;++x){
     9             ans+=pow(x/1000000.0L,data[i]);
    10         }printf("%.10Lf
    ",(long double)ans);
    11     }
    12 }
    View Code

    $Test3:$不断在$n$个变量中随机取值,求所有变量都被取过的期望步数。

    求取到下一个没取过的变量的期望步数进行累加。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
     4 int sta[11111];
     5 int main(){
     6     freopen("random3.out","w",stdout);
     7     for(int i=0;i<10;++i){
     8         __float128 ans=0;
     9         for(int j=1;j<=data[i];++j)ans+=1.0L/j;
    10         printf("%.10Lf
    ",(long double)(ans*data[i]));
    11     }
    12 }
    View Code

    $Test4:$不断在$n$个变量中随机取值,求某一个变量被取过两次的期望步数。

    枚举步数,计算概率进行累加,概率很好算是个前缀积。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
     4 int main(){
     5     freopen("random4.out","w",stdout);
     6     for(int i=0;i<=9;++i){
     7         __float128 pre=1,ans=0;
     8         for(int t=1;t<=data[i];++t){
     9             ans+=pre*t/data[i]*(t+1);
    10             pre*=((__float128)data[i]-t+0.0L)/data[i];
    11         }printf("%.10Lf
    ",(long double)ans);
    12     }
    13 }
    View Code

    $Test5:$求线段树区间询问时期望涉及多少个节点。

    考虑每个节点会在多少个方案中出现,当且仅当询问区间与当前节点区间相交且不包含父节点的完整区间。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
     4 __float128 ans,all;int I;
     5 void build(int l,int r,int fl,int fr){
     6     int lp=l-1,rp=data[I]-r;
     7     ans+=all-(lp+1.0L)*lp/2-(rp+1.0L)*rp/2-1.0L*fl*(data[I]-fr+1);
     8     if(l==r)return;
     9     build(l,l+r>>1,l,r);build((l+r>>1)+1,r,l,r);
    10 }
    11 int main(){
    12     freopen("random5.out","w",stdout);
    13     for(int i=0;i<=9;++i){I=i;
    14         ans=0;all=(data[i]+1.0L)*data[i]/2;build(1,data[i],0,-1);
    15         printf("%.10Lf
    ",(long double)(ans/all));
    16     }
    17 }
    View Code

    $Test6:$求$Treap$期望深度和。

    考虑加入一个节点的贡献,设$dp[n]$为$n$个节点的树的答案,那么$dp[n]=frac{sumlimits_{i=1}^{n} dp[i-1]+dp[n-i]}{n}$。

    上边那个就是一个前缀和。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 long double dp[1000005],pre[1000005];
     4 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
     5 int main(){
     6     freopen("random6.out","w",stdout);
     7     dp[1]=pre[1]=1;
     8     for(int i=2;i<=data[9];++i)dp[i]=2*pre[i-1]/i+i,pre[i]=pre[i-1]+dp[i];
     9     for(int i=0;i<=9;++i)printf("%.10Lf
    ",dp[data[i]]);
    10 }
    View Code

    $Test7:$不会。

    $Test8:$不断在$n$个变量中随机取值,不会取到已经取过的,取到时它的所有倍数也被取到。求所有变量都被取过的期望步数。

    每个节点被取到之可能是它的某个约数被取到,概率是均等的,所以答案是$sumlimits_{i=1}^{n} frac{1}{d(i)}$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
     4 __float128 ans;int I;
     5 int main(){
     6     freopen("random8.out","w",stdout);
     7     for(int i=0;i<=9;++i){
     8         ans=0;
     9         for(int x=1;x<=data[i];++x){
    10             int cnt=0;
    11             for(int y=1;y*y<=x;++y)if(x%y==0){
    12                 cnt++;if(y*y!=x)cnt++;
    13             }
    14             ans+=1.0L/cnt;
    15         }
    16         printf("%.10Lf
    ",(long double)ans);
    17     }
    18 }
    View Code

    $Test9:$值域为$10$,长度为$n$的随机序列的期望$LIS$。

    当$n$很大时答案直接近似成$10$。小点十进制压状态记搜$0.05s$都跑不到。

    $LIS$的转移只与前面每个值对应的最大$dp$值有关,压起来就搜就行了,实际上$1000$的点都跑不到$0.5s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int data[]={1,10,100,1024,10000,20000,50000,100000,524288,1000000};
     4 unordered_map<int,long double>M[101];
     5 int I,a[11],dp[11];long long ans,tms;
     6 int r[101][11],rr[101][11];
     7 long double sch100(int stp,int st){
     8     if(M[stp].find(st)!=M[stp].end())return M[stp][st];
     9     if(stp>6)cerr<<stp<<' '<<st<<endl;
    10     if(!stp)return st%10;int rst=st;
    11     for(int i=10;i;--i)r[stp][i]=st%10,st/=10;
    12     long double tot=0;
    13     for(int c=1;c<=10;++c){
    14         for(int i=1;i<=10;++i)rr[stp][i]=r[stp][i];
    15         rr[stp][c]=max(rr[stp][c],rr[stp][c-1]+1);
    16         if(c==10&&rr[stp][10]==10){tot+=1;break;}
    17         for(int s=c+1;s<=10;++s)rr[stp][s]=max(rr[stp][s],rr[stp][s-1]);
    18         register int nst=0;
    19         for(int i=1;i<=10;++i)nst=(nst<<3)+(nst<<1)+rr[stp][i];
    20         tot+=0.1*sch100(stp-1,nst);
    21     }return M[stp][rst]=tot;
    22 }
    23 int main(){
    24     freopen("random9.out","w",stdout);
    25     printf("%.10Lf
    ",sch100(100,0));
    26 }
    View Code

    $Test10:$不会。

  • 相关阅读:
    MFC tab页面中获到其它页面的数据
    sqlite数据库中"Select * From XXX能查到数据,但是Select DISTINCT group From xxx Order By group却查不出来
    关闭程序出现崩溃(exe 已触发了一个断点及未加载ucrtbased.pdb)
    springboot 通用Mapper使用
    springBoot 发布war包
    springCloud Zuul网关
    springboot hystrix turbine 聚合监控
    springBoot Feign Hystrix Dashboard
    springBoot Ribbon Hystrix Dashboard
    springBoot Feign Hystrix
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12208699.html
Copyright © 2011-2022 走看看