zoukankan      html  css  js  c++  java
  • [考试反思]0116省选模拟9:赌注

    又是运气场。。。

    T2有一大堆结论不是很可想。T1暴力分给了20剩下的十分麻烦。T3是个十合一。

    什么神奇考试。。。

    考场上看了一下前两题觉得不是很可做。

    于是直接奔着提答去了,最后只剩下100分钟的时候才回来看前两题。

    然后还是觉得T1数上树非常恶心于是式子都没化打暴力跑路,T2打结论啥也想不出来,只考虑了第一种情况扔上继续跑路。

    于是又一次跑到了T3。

    然而非常弱智,T1的根号筛欧拉函数又写挂了。

    第三行i写成x了。弱智

    然后T3的第7个点我居然把样例文件交上去了。。。。

    而且T3的第5个点还没想到用欧拉函数求逆元

    然后第8个点的类原题的做法也忘掉了

    后来改题的时候线筛欧拉函数又写错了

    过年回家希望有人能送我个好使点的脑子。。。

    这场考试也纯粹是运气好,平时提答做的比较多所以占了点便宜。

    而且刚题了还赶上没看的题基本不可做。。。

    下次要注意。

    T1:Surprise me

    大意:给定树,求树上所有点对$(u,v)$的$dis(u,v)varphi(u)varphi(v)$的期望。$n le 200000$

    还是用到那个结论:$varphi(ab)=frac{varphi(a)varphi(b) gcd(a,b)}{varphi(gcd(a,b))}$

    把$gcd$提出去,反演化式子,得到$sumlimits_{p=1} f(p) sumlimits_{i=1}^{frac{n}{p}} sumlimits_{j=1}^{frac{n}{p}} dep_{ip} varphi(ip) varphi(jp) +dep_{jp} varphi(ip) varphi(jp) -2dep_{lca(ip,jp) varphi(ip) varphi(jp)}$

    其中$f(p)=sumlimits_{d|p} frac{d}{varphi(d)} mu(frac{p}{d})$

    对于要求的式子,前两部分可以乘法分配律求和直接处理。最后一个部分考虑树上$dp$

    发现一共只涉及到了$n ln n$个点,每次只对需要的点做复杂度就没什么问题了。于是想到虚树。

    虚树这种东西其实不是特别难,大概意思就是把所有要求的点按照$dfn$排序后依次考虑相邻两项的$lca$,用栈维护时分类讨论连边。

    这道题的思路其实也不是特别难,但是代码是真的恶心。。。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 1000000007
     4 #define S 400005
     5 int n,r[S],dep[S],eu[S],dfn[S],fir[S],l[S],to[S],ec,T,ST[19][S],bin[S],F[S];
     6 int p[S],pc,mu[S],phi[S],np[S],iv[S],sum[S],ans,sta[S],tp,rp[S],sphi[S];
     7 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;}
     8 int mo(int a){return a>=mod?a-mod:a;}
     9 void dfs(int p,int fa){
    10     dep[p]=dep[fa]+1;eu[++T]=p;dfn[p]=T;
    11     for(int i=fir[p];i;i=l[i])if(to[i]!=fa)dfs(to[i],p),eu[++T]=p;
    12 }
    13 int lca(int x,int y){
    14     x=dfn[x];y=dfn[y];if(x>y)swap(x,y);
    15     int B=bin[y-x+1];
    16     return dep[ST[B][x]]<dep[ST[B][y-(1<<B)+1]]?ST[B][x]:ST[B][y-(1<<B)+1];
    17 }
    18 int cmp(int a,int b){return dfn[a]<dfn[b];}
    19 void DFS(int p,int rat){
    20     sphi[p]=0;
    21     for(int i=fir[p];i;i=l[i])DFS(to[i],rat),sphi[p]=mo(sphi[p]+sphi[to[i]]);
    22     rat=1ll*rat*dep[p]%mod;
    23     for(int i=fir[p];i;i=l[i])
    24         ans=mo(ans+mod-1ll*rat*sphi[to[i]]%mod*mo(mod+sphi[p]-sphi[to[i]])%mod),
    25         ans=mo(ans+mod-2ll*rat%mod*sphi[to[i]]%mod*phi[p]*rp[p]%mod);
    26     ans=mo(ans+mod-1ll*rp[p]*phi[p]*phi[p]%mod*rat%mod);
    27     sphi[p]=mo(sphi[p]+phi[p]*rp[p]);
    28     fir[p]=rp[p]=0;
    29 }
    30 int main(){
    31     scanf("%d",&n);
    32     for(int i=1,x;i<=n;++i)scanf("%d",&x),r[i]=x;
    33     for(int i=1,a,b;i<n;++i)scanf("%d%d",&a,&b),link(r[a],r[b]),link(r[b],r[a]);
    34     dfs(1,0);
    35     for(int i=1;i<=T;++i)ST[0][i]=eu[i];
    36     for(int i=1;i<=18;++i)for(int j=1<<i;j<1<<i+1&&j<=T;++j)bin[j]=i;
    37     for(int i=1;i<=18;++i)for(int j=1;j+(1<<i)-1<=T;++j)
    38         ST[i][j]=ST[i-1][dep[ST[i-1][j]]<dep[ST[i-1][j+(1<<i-1)]]?j:j+(1<<i-1)];
    39     mu[1]=phi[1]=iv[1]=1;
    40     for(int i=2;i<=n;++i){
    41         if(!np[i])p[++pc]=i,mu[i]=-1,phi[i]=i-1;
    42         for(int j=1,x;j<=pc&&(x=i*p[j])<=n;++j)
    43             if(i%p[j])np[x]=1,mu[x]=-mu[i],phi[x]=phi[i]*(p[j]-1);
    44             else{np[x]=1;phi[x]=phi[i]*p[j];break;}
    45     }
    46     for(int i=2;i<=n;++i)iv[i]=mod-1ll*mod/i*iv[mod%i]%mod;
    47     for(int d=1;d<=n;++d)for(int g=d;g<=n;g+=d)
    48         F[g]=(F[g]+1ll*d*iv[phi[d]]*mu[g/d]%mod)%mod,sum[d]=mo(sum[d]+phi[g]);
    49     for(int i=1;i<=n;++i)F[i]=mo(F[i]%mod+mod),fir[i]=0;
    50     for(int p=1;p<=n;++p){
    51         int d=0,N=n/p,rt;ec=0;
    52         for(int i=p;i<=n;i+=p)d=(d+1ll*dep[i]*phi[i])%mod,r[i/p]=i,rp[i]=1;
    53         ans=(ans+2ll*d*sum[p]%mod*F[p])%mod;
    54         sort(r+1,r+1+N,cmp);
    55         rt=r[1];for(int i=2;i<=N;++i)rt=lca(rt,r[i]);tp=0;
    56         for(int i=1,l;i<=N;++i){
    57             if(!tp)goto E;
    58             l=lca(r[i],sta[tp]);
    59             if(l==sta[tp])goto E;
    60             while(tp>1&&dfn[l]<=dfn[sta[tp-1]])link(sta[tp-1],sta[tp]),tp--;
    61             if(sta[tp]!=l)link(l,sta[tp]),sta[tp]=l;
    62 E:            sta[++tp]=r[i];
    63         }while(tp>1)link(sta[tp-1],sta[tp]),tp--;
    64         DFS(rt,mo(F[p]<<1));
    65     }
    66     printf("%lld
    ",1ll*ans*iv[n]%mod*iv[n-1]%mod);
    67 }
    View Code

    T2:过河(river)

    大意:送$n$猪过河,有$m$个三元关系,如果这三个在同一岸就非法。每次运一个可以往回运。问能否过河。$nle 1000,mle 3000$

    如果所有三元关系的交集为空,一定非法,因为第一遍过去时剩在这一岸的一定会打架。

    所以我们提出它们的交集,剩下一些二元组看成边。边上两点不能在同一岸,这些条件是否矛盾就看它是否存在奇环。

    否则进行奇偶染色后就是一种合法的分岸方法。

    特别的我们要考虑运那只特殊的猪,在它前后运的那两只并不会产生矛盾(因为特殊的猪在船上)

    转化问题:给定图,去掉两个点之后是否为二分图。

    暴力就是枚举两个点。要注意判断输入数据中三元环有元素相同的情况。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,fir[1001],l[6003],to[6003],a[3111],b[3111],c[3111],P,co[1111],ok,ec;
     4 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;l[++ec]=fir[b];fir[b]=ec;to[ec]=a;}
     5 void dfs(int p,int c){
     6     co[p]=c;
     7     for(int i=fir[p];i&&ok;i=l[i])if(!co[to[i]])dfs(to[i],c^1);
     8         else if(co[to[i]]==co[p])ok=0;
     9 }
    10 int main(){//freopen("river1.in","r",stdin);
    11     int t;cin>>t;while(t-->0){
    12         cin>>n>>m;P=0;
    13         for(int i=1;i<=m;++i){cin>>a[i]>>b[i]>>c[i];if(a[i]==b[i]||b[i]==c[i])i--,m--;}
    14         for(int i=1;i<=n;++i){
    15             for(int j=1;j<=m;++j)if(a[j]==i||b[j]==i||c[j]==i);else goto X;
    16             P=i;X:;
    17         }
    18         if(!P){puts("no");continue;}
    19         for(int i=1;i<=n;++i)if(i!=P)for(int j=i+1;j<=n;++j)if(j!=P){
    20             for(int k=1;k<=n;++k)co[k]=fir[k]=0;ec=0;
    21             for(int k=1;k<=m;++k)
    22                 if(a[k]==P){if(b[k]!=i&&b[k]!=j&&c[k]!=i&&c[k]!=j)link(b[k],c[k]);}
    23                 else if(b[k]==P){if(a[k]!=i&&a[k]!=j&&c[k]!=i&&c[k]!=j)link(a[k],c[k]);}
    24                 else {if(b[k]!=i&&b[k]!=j&&a[k]!=i&&a[k]!=j)link(b[k],a[k]);}
    25             ok=1;
    26             for(int k=1;k<=n&&ok;++k)if(!co[k])dfs(k,2);
    27             if(ok)goto Y;
    28         }Y:puts(ok?"yes":"no");
    29     }
    30 }
    View Code

    正解是枚举去掉的第一个点,对于其余边建出$dfs$树,看哪些点能够成为被删的第二个点。

    这个点需要存在在所有的奇环内。而所有的奇环在$dfs$树上的表现形式只有两种:

    1,返祖边+树边。其中返祖边跨越的树上距离为偶数。

    2,两条返祖边+树边。其中两条返祖边的树上距离一奇一偶。

    对于第一种情况我们打一个差分标记记录就可以。

    对于第二种情况,我们在判断点$p$时,要保证$p$的每一个儿子的子树不存在一奇一偶的返祖边。

    注意这里所说的第二种情况是对于每一个儿子的子树考虑的,而不是所有儿子加起来。

    第二种情况的判断方法我想$xm$学的大神做法,像$tarjan$一样记一个回溯值按照深度判就行了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,fir[1001],l[6003],to[6003],a[3111],b[3111],c[3111],P,ok,ec;
     4 int odd[1111],dep[1111],oddcnt,f[1111],Odd[1111],Even[1111];
     5 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;l[++ec]=fir[b];fir[b]=ec;to[ec]=a;}
     6 void dfs(int p,int fa){
     7     dep[p]=dep[fa]+1;f[p]=fa;
     8     for(int i=fir[p];i;i=l[i])if(to[i]!=fa)
     9         if(!dep[to[i]])dfs(to[i],p),odd[p]+=odd[to[i]],Even[p]=min(Even[p],Even[to[i]]),Odd[p]=min(Odd[p],Odd[to[i]]);
    10         else if(dep[p]-dep[to[i]]&1){if(dep[to[i]]<dep[p])Even[p]=min(Even[p],dep[to[i]]);}
    11         else if(dep[to[i]]<dep[p])odd[p]++,odd[f[to[i]]]--,oddcnt++,Odd[p]=min(Odd[p],dep[to[i]]);
    12 }
    13 int main(){//freopen("river1.in","r",stdin);
    14     int t;cin>>t;while(t-->0){
    15         cin>>n>>m;P=0;
    16         for(int i=1;i<=m;++i)cin>>a[i]>>b[i]>>c[i];
    17         for(int i=1;i<=n;++i){
    18             for(int j=1;j<=m;++j)if(a[j]==i||b[j]==i||c[j]==i);else goto X;
    19             P=i;X:;
    20         }
    21         if(!P){puts("no");continue;}
    22         for(int x=1;x<=n;++x){
    23             for(int i=1;i<=n;++i)fir[i]=odd[i]=dep[i]=f[i]=0,Odd[i]=Even[i]=1234567;ec=1;oddcnt=ok=0;
    24             for(int i=1;i<=m;++i)
    25                 if(a[i]==P){if(b[i]!=x&&c[i]!=x)link(b[i],c[i]);}
    26                 else if(b[i]==P){if(a[i]!=x&&c[i]!=x)link(a[i],c[i]);}
    27                 else if(c[i]==P){if(a[i]!=x&&b[i]!=x)link(a[i],b[i]);}
    28             for(int i=1;i<=n;++i)if(i!=x&&i!=P&&!dep[i])dfs(i,0);
    29             for(int i=1;i<=n;++i)if(odd[i]==oddcnt){
    30                 int r=1;
    31                 for(int j=fir[i];j;j=l[j])if(dep[to[j]]>dep[i]&&Even[to[j]]<dep[i]&&Odd[to[j]]<dep[i])r=0;
    32                 ok|=r;
    33             }if(ok)break;
    34         }puts(ok?"yes":"no");
    35     }
    36 }
    View Code

    T3:NPIO十合一

    大意:无题面。给出$10$份超慢$std$与数据生成/输出生成代码,求解答案。

    National Programming Informatic Olympic???

    若答案数组为$c$。输出生成方式$x=(233 imes x   xor c[i])mod 1000000007$

    $Test1:$读入数组$a,b$对位求和后输出。数组大小$10^9$

    模拟题意生成数据并输出即可。预计耗时$18s$。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main(){
     4     freopen("npio1.out","w",stdout);
     5     const int n=1000000000;register int x=233,y=233,res=0;
     6     for(int i=1;i<=n;++i)x=(37*x+666)%19260817;
     7     for(int i=1;i<=n;++i)
     8         x=(37*x+666)%19260817,
     9         y=(37*y+666)%19260817,
    10         res=(233LL*res^x%10000+y%10000)%1000000007;
    11     cout<<res<<endl;
    12 }
    View Code

    $Test2:$读入数组$a,b$卷积后输出。数组大小$5000000$。值域$2^{15}$。常系数线性齐次递推生成。

    可以$MTT/FFT?$我用的$Test3$的方法。预计耗时$2s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int bit=1<<15;
     4 int A[bit],B[bit],C[bit<<1];
     5 int main(){
     6     freopen("npio2.out","w",stdout);
     7     const int n=5000000;register int x=23333;
     8     for(int i=0;i<bit;++i)A[i]=x=(233*x+37)&32767;
     9     for(int i=bit;i<n;++i)x=(233*x+37)&32767;
    10     for(int i=0;i<bit;++i)B[i]=x=(233*x+37)&32767;
    11     for(int i=0;i<bit;++i)for(int j=0;j<bit;++j)C[i+j]=(C[i+j]+A[i]*B[j])%998244353;
    12     register int ans=0;
    13     for(int i=0;i<n;++i){
    14         register int bl=i>>15,lw=i&32767,tmp=(C[lw]*(bl+1ll)+1ll*bl*C[lw|bit])%998244353;
    15         if(i%1000000==0)cerr<<i<<endl;
    16         ans=(ans*233LL^tmp)%1000000007;
    17     }cout<<ans<<endl;
    18 }
    View Code

    $Test3:$读入数组$a,b$卷积后输出。数组大小$10^9$。值域$2^{15}$。常系数线性齐次递推生成。

    根据生成方式发现有循环节,打出来发现循环节恰好为$2^{15}$。于是直接做$2^{16}$的卷积就行了。

    然后乘上错位的系数即可。预计耗时$28s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int bit=1<<15;
     4 int A[bit],B[bit],C[bit<<1];
     5 int main(){
     6     freopen("npio3.out","w",stdout);
     7     const int n=1000000000;register int x=23333;
     8     for(int i=0;i<bit;++i)A[i]=x=(233*x+37)&32767;
     9     for(int i=bit;i<n;++i)x=(233*x+37)&32767;
    10     for(int i=0;i<bit;++i)B[i]=x=(233*x+37)&32767;
    11     for(int i=0;i<bit;++i)for(int j=0;j<bit;++j)C[i+j]=(C[i+j]+A[i]*B[j])%998244353;
    12     register int ans=0;
    13     for(int i=0;i<n;++i){
    14         register int bl=i>>15,lw=i&32767,tmp=(C[lw]*(bl+1ll)+1ll*bl*C[lw|bit])%998244353;
    15         if(i%1000000==0)cerr<<i<<endl;
    16         ans=(ans*233LL^tmp)%1000000007;
    17     }cout<<ans<<endl;
    18 }
    View Code

    $Test4:$排序$a$数组。数组大小与值域是$10^9$。

    发现循环节很长。。。开$short$直接桶排,重复的数不多。预计耗时$45s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 short M[1000000001];
     4 int main(){
     5     freopen("npio4.out","w",stdout);
     6     unsigned int x=23333;
     7     for(int i=1;i<=1000000000;++i){
     8         x=x^(x<<13);
     9         x=x^(x>>17);
    10         x=x^(x<<5);
    11         M[x%1000000000]++;
    12         if(i%100000==0)cerr<<i<<endl;
    13     }int ans=0;
    14     for(int i=0;i<1000000000;++i)while(M[i])
    15         M[i]--,ans=(233LL*ans^i)%1000000007;
    16     cout<<ans<<endl;
    17 }
    View Code

    $Test5:$随机树。按序输出子树大小。数组大小$10^9$。常系数线性齐次递推生成。模数$233$进制数$2^{32}$

    考场上没想出来。

    应该算是最难的一个。可以发现模数与进制数互质,存在逆元$233^{2^{31}-1}$。

    所以可以倒推回来存子树大小。大小数组对于较小的位置开$int$较大位置开$short$。$int$开得越多越好。

    预计耗时$43s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 short d[1000000001];int D[270000001];
     4 inline int addd(register const int&p,register const int&w){
     5     if(p<=270000000)D[p]+=w;
     6     else d[p]+=w;
     7 }
     8 inline int deg(register const int&p){
     9     if(p<=270000000)return D[p];
    10     else return (int)d[p];
    11 }
    12 int main(){
    13     freopen("npio5.out","w",stdout);
    14     const int n=1000000000;register unsigned int x=23333,iv=233,Iv=1;register int ans=0;
    15     for(int i=0;i<31;++i)Iv*=iv,iv*=iv;iv=Iv;
    16     for(int i=1;i<n;++i)x=233*x+37;
    17     for(int i=1;i<=n;++i)addd(i,1);
    18     for(int i=n-1;i;--i){
    19         int fa=x%i+1;addd(fa,deg(i+1));
    20         x-=37;x*=iv;
    21         if(i%1000000==0)cerr<<i<<endl;
    22     }
    23     for(int i=1;i<=n;++i)ans=(233LL*ans^deg(i))%1000000007;
    24     cout<<deg(1)<<' '<<ans<<endl;
    25 }
    View Code

    $Test6:$随机基环树。随机树加一条边求最小生成树。数据范围$10^9$。值域$2^{15}$

    最机智的做法取模$Dyyb$。因为值域只有$2^{15}$所以依次尝试去掉这个边权的边,和样例拍上就行。

    我的弱智做法是因为随机树期望深度为$ln$级别,所以爆跳父亲求$lca$,找环上最小边。预计耗时$6s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int n=1000000000;
     4 int fx[11111],tfx[11111],fy[11111],tfy[11111],cfx,cfy,ans,r[4],tans;
     5 int main(){
     6     freopen("npio6.out","w",stdout);
     7     unsigned int x=23333,w=233,a,b;
     8     for(int i=1;i<n;++i)x=233*x+37,w=23*w+37&32767;
     9     x=a=233*x+37;b=233*x+37;ans=23*w+37&32767;
    10     fx[0]=a=a%n+1,fy[0]=b=b%n+1;
    11     //cout<<a<<' '<<b<<endl;
    12     while(a!=1){
    13         x=23333;w=233;cfx++;
    14         for(int i=1;i<a;++i)x=233*x+37,w=(23*w+37)&32767;
    15         a=fx[cfx]=x%(a-1)+1;tfx[cfx]=w;//cerr<<a<<endl;
    16     }//cout<<cfx<<endl;
    17     while(b!=1){
    18         x=23333;w=233;cfy++;
    19         for(int i=1;i<b;++i)x=233*x+37,w=(23*w+37)&32767;
    20         b=fy[cfy]=x%(b-1)+1;tfy[cfy]=w;
    21     }//cout<<cfy<<endl;
    22     for(int i=0;i<=cfx;++i)for(int j=0;j<=cfy;++j)if(fx[i]==fy[j]){
    23         for(int k=1;k<=i;++k)ans=max(ans,tfx[k]);
    24         for(int k=1;k<=j;++k)ans=max(ans,tfy[k]);
    25         goto O;
    26     }O:
    27     w=233;
    28     long long nans=-ans;
    29     for(int i=1;i<=n;++i)w=23*w+37&32767,nans+=w;
    30     for(int i=0;i<4;++i)r[i]=nans%10000,nans/=10000;
    31     for(int i=0;i<4;++i)tans=(tans*233LL^r[i])%1000000007;
    32     cout<<tans<<endl;
    33 }
    View Code

    $Test7:$维护堆支持插入/弹顶。每次操作后堆顶为答案。操作数及值域$10^9$。操作是随机的。

    因为期望下弹与加次数相同,所以直接暴力模拟。元素个数始终没有超过$30000$所以不太慢。

    预计耗时$1min$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 priority_queue<int>Q;
     4 const int n=1000000000,mod=1000000009;
     5 int main(){
     6     freopen("npio7.out","w",stdout);
     7     int sz=0,y=23333,ans=0;unsigned int x=233;
     8     for(int i=1;i<=n;++i){
     9         x=(x*23+777)%19260817;
    10         if(sz<2||(!(x&1)))y=y*233+567,Q.push(y),++sz;
    11         else Q.pop(),sz--;
    12         if(i%10000000==0)cerr<<i<<' '<<sz<<endl;
    13         ans=(233LL*ans^(Q.top()%mod+mod)%mod)%1000000007;
    14     }cout<<ans<<endl;
    15 }
    View Code

    $Test8:$动态加入数,每次加入后中位数为答案。操作数及值域$10^9$。数据随机。

    考场上没想出来。

    类似于原题。以前有一个是$2 imes 10^9$之内所有质数乘什么东西来着。

    循环节还是很长,开$short$桶维护每个数出现次数,维护一个指针表示当前值与这个值的排名。

    在随机数据下指针的移动次数很少。刚开始跑的慢后来密集之后很快。

    预计耗时$70s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 short v[1000000000];
     4 int main(){freopen("npio8.out","w",stdout);
     5     const int n=1000000000;register unsigned int x=23333;
     6     register int p=0,rk=0,ans=0;
     7     for(int i=1;i<=n;++i){
     8         x=233*x+37;
     9         v[x%1000000000]++;
    10         if(x%1000000000<p)rk++;
    11         while(rk+v[p]<i+1>>1)rk+=v[p],p++;
    12         while(rk+1>i+1>>1)p--,rk-=v[p];
    13         ans=(233LL*ans^p)%1000000007;
    14         if(i%10000000==0)cerr<<i<<endl;
    15     }
    16     cout<<ans<<endl;
    17 }
    View Code

    $Test9:$动态加入数,每次加入后有多少种数即为答案。操作数及值域$10^9$。

    $bitset$直接搞就可以。编译预计耗时$70s$。运行预计耗时$50s$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 bitset<1000000000>B;
     4 const int n=1000000000,mx=1000000000;
     5 int main(){
     6     freopen("npio9.out","w",stdout);
     7     register unsigned int x=23333,ans=0,r=0;
     8     for(int i=1;i<=n;++i){
     9         x=233*x+37;
    10         if(!B[x%mx])ans++;
    11         B[x%mx]=1;
    12         if(i%10000000==0)cerr<<i<<' '<<ans<<endl;
    13         r=(233LL*r^ans)%1000000007;
    14     }cout<<r<<endl;
    15 }
    View Code

    $Test10:$求各个点双中点的编号和,排序后依次输出。点数$10^7$。边数$10^9$。边随机。

    生成方式为$x=x imes 233 +37,y=y imes 23+37$。$unsigned int$自然溢出。$x,y$初值为$23333,777$

    考场上没想出来。

    可以发现$x,y$的奇偶性时刻相同。所以奇点之间联通,偶点之间联通。

    因为点少边多,所以在随机数据下每个联通块都是点双。

    所以所有奇点在一个点双里,所有偶点在一个点双里。直接比较输出即可。

    预计耗时$0s$

    1 #include<bits/stdc++.h>
    2 using namespace std;
    3 int main(){
    4     freopen("npio10.out","w",stdout);
    5     register int x=5000001*5000000ll%998244353,y=5000000*5000000ll%998244353;
    6     cout<<(233ll*y^x)%1000000007<<endl;
    7 }
    View Code

    .

  • 相关阅读:
    几种常见的基于Lucene的开源搜索解决方案对比
    【例子】Bobobrowse:lucene分组统计扩展组件
    Solr 相似页面MoreLikeThis
    eclipse安装、基本使用、常用设置
    iPhone开发入门守则:ObjectiveC编码规范系列教程
    ios开发学习按钮(Button)效果源码分享
    ios开发学习音频声效(Audio)效果源码分享系列教程
    ios开发学习动画(Animation)效果源码分享系列教程1
    ios开发学习图表(Chart)效果源码分享系列教程
    局网满猿关不住,一波码农出墙来。
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12201188.html
Copyright © 2011-2022 走看看