zoukankan      html  css  js  c++  java
  • [考试反思]0303省选模拟36:反常

     

    我并没有咕博客啊模拟测试的编号突然跳了一个我也不知道为啥。

    这场依旧没啥好说的。

    $T1$大概是联赛难度了。。。模拟?不好说。

    太简朴反而容易让人想复杂。我都不知道想到哪里去了幸亏最后收住了。

    然后$T2$卡了一下常数所以比没卡的多了4分。

    然而$T3$写炸了,常数过大被卡成成$5$分。

    大体发挥正常吧。

    $T2$思路挺奇妙的,想不到。

    但是$T3$考后也没太看明白,多项式的奇怪扩展,还得花时间回头弄它。。

    T1:Alchemy

    大意:给定$hanoi$局面。判断它是最优解的第几步。$n le 50$

    模拟?就挨个判断每个盘子在哪里就好了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int p[55],t,n,ok;
     4 long long sch(int x,int f,int t,int e){
     5     if(!x)return 0;
     6     if(p[x]==e)return ok=0;
     7     if(p[x]==f)return 1ll<<x-1|sch(x-1,f,e,t);
     8     if(p[x]==t)return sch(x-1,e,t,f);
     9 }
    10 int main(){
    11     cin>>t;while(t--){
    12         ok=1;n=0;
    13         for(int i=0,k,x;i<3;++i){
    14             scanf("%d",&k);n+=k;
    15             while(k--)scanf("%d",&x),p[x]=i;
    16         }
    17         long long r=sch(n,0,2,1);
    18         if(ok)cout<<r<<endl;else puts("No");
    19     }
    20 }
    View Code

    T2:Algebra

    大意:求大于等于$n$的最小的满足在$a,b$进制下每位的和相等的数。$n le 10^{16},a,b, le 36$

    设一个$next(n,k,s)$表示大于等于$n$的最小的$k$进制下和为$s$的数。这个可以逐位贪心。

    然后我们用一个类似最短路的方法把所有的$(n,s)pair$扔进堆里。每次取出一个扩展。

    如果$next(n,a,s)=next(n,b,s)=n$那么就可以输出答案了。否则将$(max(next(n,a,s),next(n,b,s)),s)$丢进去。

    最终的答案是$O(n)$级别的所以可以说明有效的$s$最大也就$400$左右

    由于进位这种操作所以$next(a)$与$next(b)$交错分布的规律是随机的。而根据生日悖论,$next$的调用次数只有$O(sqrt{n})$次。

    而且常数比较小所以可以通过。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 struct x{
     5     ll n;int s;
     6     friend bool operator<(x a,x b){return a.n>b.n;}
     7 };priority_queue<x>q;
     8 int mxt[38],bit[65],b[65];ll pw[38][65];
     9 bool chk(int al,int k,int s){
    10     for(int i=al;~i;--i)b[i]=0;
    11     int p=al;
    12     while(s>=k-1){
    13         if(bit[p]<k-1)return 1;
    14         b[p]=k-1,p--,s-=k-1;
    15     }
    16     b[p]=s;if(s>bit[p])return 1;else if(s<bit[p])return 0;
    17     for(int i=p;~i;--i)if(b[i]>bit[i])return 1;else if(b[i]<bit[i])return 0;
    18     return 1;
    19 }
    20 ll sch(int al,int k,int s,int lim=1){
    21     if(al==-1)return 0;
    22     for(int x=max(lim?bit[al]:0,s-(k-1)*al);x<k&&x<=s;++x)if(!lim||x>bit[al]||chk(al-1,k,s-x))
    23         return sch(al-1,k,s-x,lim&x==bit[al])+pw[k][al]*x;
    24     return 1ll<<62;
    25 }
    26 ll nxt(ll n,int k,int s){
    27     for(int i=0;i<65;++i)bit[i]=0;
    28     int cnt=0;
    29     while(n)bit[cnt]=n%k,n/=k,cnt++;
    30     return sch(mxt[k]-1,k,s);
    31 }
    32 int main(){
    33     for(int i=2;i<37;++i){
    34         pw[i][0]=1;
    35         while(pw[i][mxt[i]]<1ll<<55)++mxt[i],pw[i][mxt[i]]=pw[i][mxt[i]-1]*i;
    36         ++mxt[i],pw[i][mxt[i]]=pw[i][mxt[i]-1]*i;
    37     }
    38     int t;cin>>t;while(t--){
    39         ll n;int a,b,s;cin>>n>>a>>b;
    40         for(int s=0;s<400;++s)q.push((x){n,s});
    41         while(1){
    42             n=q.top().n;s=q.top().s;q.pop();
    43             ll A=nxt(n,a,s),B=nxt(n,b,s);
    44             if(A==B&&A==n){cout<<n<<endl;goto E;}
    45             q.push((x){max(A,B),s});
    46         }E:;while(!q.empty())q.pop();
    47     }
    48 }
    View Code

    T3:Anarchy

    大意:高维多项式卷积。$n=prod times_i le 10^5$

    大概意思是,我们需要构造一种$DFT$使之满足:

    设$i,j,y$为两个高维向量。那么$ans_y = sumlimits_{i + j = y} x_i imes y_j$

    其中条件中的加号,是模意义下,每一维都相等。

    发现这个条件,只需要依次对每一维都做一遍循环卷积的$DFT$就好了。

    最低维显然成立,更高维只是将数替换成了序列,是一样的。对每一维分别做就可以了。

    所以就可以做$DFT$了。这样的复杂度是$O(nsum times_i)$的。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 333333
     4 int n,m,Q,s[22]; double A,rt[S];
     5 struct cp{double r,i;
     6     cp(){} cp(double a,double b):r(a),i(b){}
     7     cp operator*(cp x){return cp(r*x.r-i*x.i,r*x.i+i*x.r);}
     8     cp operator+(cp x){return cp(r+x.r,i+x.i);}
     9 }a[S],d[S],t[S],T[S]; vector<cp>w[2][22];
    10 void FFT(int o,int op){
    11     for(int i=0;T[i]=cp(0,0),i<s[o];++i)for(int j=0;j<s[o];++j)T[i]=T[i]+w[op][o][i*j%s[o]]*t[j];
    12     if(!op)for(int i=0;i<s[o];++i)T[i].r/=s[o],T[i].i/=s[o]; 
    13 }
    14 void DFT(cp*a,int op=1){
    15     for(int i=1,r=1;i<=m;r*=s[i],++i)for(int j=0;j<n;j+=r*s[i])for(int k=0;k<r;++k){
    16         for(int l=0;l<s[i];++l)t[l]=a[j+k+l*r];
    17         FFT(i,op);
    18         for(int l=0;l<s[i];++l)a[j+k+l*r]=T[l];
    19     }
    20 } 
    21 int main(){
    22     cin>>Q;while(Q--){
    23         cin>>m; n=1;
    24         for(int i=1;i<=m;++i)cin>>s[i],n*=s[i],w[1][i].resize(s[i]),w[0][i].resize(s[i]);
    25         for(int i=1;i<=m;++i)for(int j=0;j<s[i];++j) A=2*acos(-1)/s[i]*j,w[0][i][j]=cp(cos(A),sin(-A)),w[1][i][j]=cp(cos(A),sin(A));
    26         for(int i=0;i<n;++i)d[i]=cp(1,0),scanf("%lf",&a[i].r),a[i].i=0;
    27         for(int i=1;i<=n;++i)rt[i]=pow(i,2./m);
    28         for(int i=0,x;x=i,i<n;++i)for(int j=1;j<=m;++j)d[i].r*=rt[x%s[j]+1],x/=s[j];
    29         DFT(a);DFT(d); for(int i=0;i<n;++i)a[i]=a[i]*d[i]; DFT(a,0);
    30         for(int i=0;i<n;++i)rt[i]=a[i].r; sort(rt,rt+n);
    31         for(int i=n-1;i>n-101&&~i;--i)printf("%.9lf ",rt[i]/2/m);puts("");
    32     }
    33 }
    45pts

    复杂度瓶颈在于里面$DFT$那里。我们一次$DFT$是得到$A_i = sumlimits_{j=0}^{times_x-1} w_{times_x}^{ij} B_j$

    然后这个$ij$非常难办,于是转化成别的形式,$ij=frac{(i+j)^2-i^2-j^2}{2}$

    把这坨东西大概代回去大概能得到$w_{times_x}^{-frac{i^2}{2}} A_i = sumlimits_{j=0}^{times_x-1} B_j w_{times_x}^{-frac{j^2}{2}}  w_{times_x}^{frac{(i+j)^2}{2}}$

    一个经典的减法卷积。也没有长度或者循环什么的限制,于是直接做一个经典的$FFT$就可以了。

    然而其实可以利用一下循环卷积,我做题少第一次见:减法卷积平时都会翻转于是按照含义来说低位上是没有数的。

    所以这时候我们不用开长长度直接让它循环卷下来就好了,长度可以开$2n$而不用$3n$。

    然而这次没有写。这道题还卡常,所以对于长度比较小的时候还是暴力卷积。总时间复杂度是$nlog^2n$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 2222222
     4 int n,m,Q,s[22],len,rev[S]; double A,rt[S];
     5 struct cp{double r,i;
     6     cp(){} cp(double a,double b):r(a),i(b){}
     7     cp operator*(cp x){return cp(r*x.r-i*x.i,r*x.i+i*x.r);}
     8     cp operator+(cp x){return cp(r+x.r,i+x.i);}
     9     cp operator-(cp x){return cp(r-x.r,i-x.i);}
    10 }a[S],d[S],t[S],T[S],r[S],x,y; vector<cp>w[2][22],W[2][22];
    11 void fft(cp*a,int op=1){
    12     for(int i=1;i<len;++i)if(rev[i]>i)swap(a[i],a[rev[i]]);
    13     for(int i=1,c=1;i<len;i<<=1,++c)for(int j=0;j<len;j+=i<<1)for(int k=0;k<i;++k)
    14         x=a[k+j],y=a[k+j+i]*W[op][c][k],a[j+k]=x+y,a[j+k+i]=x-y;
    15     if(!op)for(int i=0;i<len;++i)a[i].r/=len,a[i].i/=len;
    16 }
    17 void FFT(int o,int op){
    18     if(s[o]<64) for(int i=0;T[i]=cp(0,0),i<s[o];++i)for(int j=0;j<s[o];++j)T[i]=T[i]+w[op][o][2ll*i*j%(2*s[o])]*t[j];
    19     else{
    20         len=1;while(len<s[o]*3)len<<=1;
    21         for(int i=0;i<len;++i)rev[i]=rev[i>>1]>>1|(i&1?len>>1:0),T[i]=cp(0,0);
    22         for(int i=0;i<s[o];++i)t[i]=t[i]*w[op^1][o][1ll*i*i%(2*s[o])];
    23         for(int i=s[o];i<len;++i)t[i]=cp(0,0);
    24         reverse(t,t+s[o]);
    25         for(int i=0;i<s[o]*2;++i)T[i]=w[op][o][1ll*i*i%(2*s[o])];
    26         fft(t);fft(T);for(int i=0;i<len;++i)T[i]=T[i]*t[i];fft(T,0);
    27         for(int i=0;i<s[o];++i)T[i]=T[i+s[o]-1]*w[op^1][o][1ll*i*i%(2*s[o])];
    28     }if(!op)for(int i=0;i<s[o];++i)T[i].r/=s[o],T[i].i/=s[o];
    29 }
    30 void DFT(cp*a,int op=1){
    31     for(int i=1,r=1;i<=m;r*=s[i],++i)for(int j=0;j<n;j+=r*s[i])for(int k=0;k<r;++k){
    32         for(int l=0;l<s[i];++l)t[l]=a[j+k+l*r];
    33         FFT(i,op);
    34         for(int l=0;l<s[i];++l)a[j+k+l*r]=T[l];
    35     }
    36 }
    37 int main(){
    38     for(int i=0;i<=21;++i)W[0][i].resize(1<<i),W[1][i].resize(1<<i);
    39     for(int i=0;i<=21;++i)for(int j=0;j<1<<i;++j) A=2*acos(-1)/(1<<i)*j,W[0][i][j]=cp(cos(A),sin(-A)),W[1][i][j]=cp(cos(A),sin(A));
    40     cin>>Q;while(Q--){
    41         cin>>m; n=1;
    42         for(int i=1;i<=m;++i)cin>>s[i],n*=s[i],w[1][i].resize(s[i]<<1),w[0][i].resize(s[i]<<1);
    43         for(int i=1;i<=m;++i)for(int j=0;j<s[i]<<1;++j) A=acos(-1)/s[i]*j,w[0][i][j]=cp(cos(A),sin(-A)),w[1][i][j]=cp(cos(A),sin(A));
    44         for(int i=0;i<n;++i)d[i]=cp(1,0),scanf("%lf",&a[i].r),a[i].i=0;
    45         for(int i=1;i<=n;++i)rt[i]=pow(i,2./m);
    46         for(int i=0,x;x=i,i<n;++i)for(int j=1;j<=m;++j)d[i].r*=rt[x%s[j]+1],x/=s[j];
    47         DFT(a);DFT(d); for(int i=0;i<n;++i)a[i]=a[i]*d[i]; DFT(a,0);
    48         for(int i=0;i<n;++i)rt[i]=a[i].r; sort(rt,rt+n);
    49         for(int i=n-1;i>n-101&&~i;--i)printf("%.9lf ",rt[i]/2/m);puts("");
    50     }
    51 }
    View Code
  • 相关阅读:
    《VR入门系列教程》之21---使用Unity开发GearVR应用
    《VR入门系列教程》之20---使用Oculus移动端SDK
    《VR入门系列教程》之19---GearVR开发初识
    《VR入门系列教程》之18---Oculus代码剖析
    《VR入门系列教程》之17---发布第一个应用
    《VR入门系列教程》之16---第一个OculusVR应用
    阿里巴巴开发手册提取信息
    国富论
    富通天下(W 笔试)
    富通天下(T 面试)
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12405384.html
Copyright © 2011-2022 走看看