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
  • 相关阅读:
    ActiveMQ 即时通讯服务 浅析
    Asp.net Mvc (Filter及其执行顺序)
    ActiveMQ基本介绍
    ActiveMQ持久化消息的三种方式
    Windows Azure Virtual Machine (27) 使用psping工具,测试Azure VM网络连通性
    Azure China (10) 使用Azure China SAS Token
    Windows Azure Affinity Groups (3) 修改虚拟网络地缘组(Affinity Group)的配置
    Windows Azure Storage (22) Azure Storage如何支持多级目录
    Windows Azure Virtual Machine (26) 使用高级存储(SSD)和DS系列VM
    Azure Redis Cache (2) 创建和使用Azure Redis Cache
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12405384.html
Copyright © 2011-2022 走看看