zoukankan      html  css  js  c++  java
  • BZOJ1423 : Optimus Prime

    设$f[x]$表示为了保证自己可以取到质数$x$,第一步在$[0,n]$中可以选的数是多少。

    这个数是唯一的,因为如果存在两个$f[x]=a,b(a<b)$,那么如果先手取了$a$,后手就能取$b$来让先手取不到$x$,矛盾。

    如果$x$与下一个质数之间的差值大于$n$,那么$f[x]$就是结果,当$f[x]=0$时先手必败。

    对于不超过$n$的$x$,$f[x]=x$。

    对于大于$n$的$x,f[x]=f[y]$,其中$y$是$x$前面最近的与它差值大于$n$的质数,可以双指针得到。

    如果没有找到终止态,取一定范围内的所有大质数的$f[x]$的众数,极有可能就是精确解。

    #include<cstdio>
    const int N=3000010,M=N/10,E=1010;
    int T,n,t,i,j,tot,p[M],f[M],c[E],ans[E];bool v[N];
    inline int cal(int n){
      if(~ans[n])return ans[n];
      int i,j;
      for(i=0;i<=n;i++)c[i]=0;
      for(i=j=0;i<=tot;i++){
        if(p[i]<=n)f[i]=p[i];
        else{
          while(j+1<i&&p[i]-p[j+1]>n)j++;
          f[i]=f[j];
        }
        if(i<tot&&p[i]+n<p[i+1])return ans[n]=f[i];
        if(i>tot/10*9)c[f[i]]++;
      }
      for(i=j=0;i<=n;i++)if(c[i]>c[j])j=i;
      for(i=0;i<=n;i++)if(i!=j&&c[i]*2>c[j])return ans[n]=0;
      return ans[n]=j;
    }
    int main(){
      for(v[1]=1,i=2;i<N;i++){
        if(!v[i])p[++tot]=i;
        for(j=1;j<=tot&&i*p[j]<N;j++){
          v[i*p[j]]=1;
          if(i%p[j]==0)break;
        }
      }
      for(i=0;i<E;i++)ans[i]=-1;
      scanf("%d",&T);
      while(T--){
        scanf("%d",&n);
        if(t=cal(n))printf("A %d
    ",t);else puts("B");
      }
      return 0;
    }
    

      

  • 相关阅读:
    Contains Duplicate
    Valid Anagram
    Invert Binary Tree
    Same Tree
    代理模式——java设计模式
    单例模式——java设计模式
    关于春招自己感到很失落这件事
    Collections.sort()中的mergeSort归并排序
    腾讯云搭建日志收集系统
    centos7 mysql
  • 原文地址:https://www.cnblogs.com/clrs97/p/7470001.html
Copyright © 2011-2022 走看看