• O(1)GCD


    #include <cstdio>
    #include <cstring>
    #define SIZE 1000
    #define U unsigned int
    using namespace std;
      
      int ss[1000001],cnt,p[1000001];
      short g[1001][1001],b[1000001];
      int f[1000001][3];
      int a[2001],bb[2001];
    
      int pregcd(int x,int y){
          if (y==0) {g[x][y]=x;return(x);}
          if (g[x][y]!=-1) return(g[x][y]);
          g[x][y]=pregcd(y,x%y);
          return(g[x][y]);
      }
      
      void euler(){
          p[1]=1;
          for (int i=2;i<=SIZE*SIZE;i++){
            if (!b[i]){
              p[i]=i;ss[++cnt]=i;
          }    
          for (int j=1;ss[j]*i<=SIZE*SIZE&&j<=cnt;j++){
              b[ss[j]*i]=1;
              p[ss[j]*i]=ss[j];
              if (i%ss[j]==0) break;
          }
        }
      }
      
      int gcd(int x,int y){
          if (x<=SIZE&&y<=SIZE) return(g[x][y]);
          int d=1;
          for (int i=0;i<=2;i++)
            if (p[f[x][i]]==f[x][i]){
              if (y%f[x][i]==0){
                d*=f[x][i];y/=f[x][i];    
            }
          }else{
              int t=g[f[x][i]][y%f[x][i]];
              d*=t;y/=t;
          }
        return(d);  
      }
      
      int main(){
          freopen("a.in","r",stdin);
          
          for (int i=0;i<=SIZE;i++)
            for (int j=0;j<=SIZE;j++)
              g[i][j]=-1;
        for (int i=0;i<=SIZE;i++)
          for (int j=0;j<=SIZE;j++)
            pregcd(i,j);//预处理SIZE以内gcd
            
        euler();
        
        f[1][0]=f[1][1]=f[1][2]=1;
        for (int i=2;i<=SIZE*SIZE;i++){
          memcpy(f[i],f[i/p[i]],sizeof(f[i]));    
          if (f[i][0]<=SIZE/p[i]) f[i][0]*=p[i];else
          if (f[i][1]<=SIZE/p[i]) f[i][1]*=p[i];else
          f[i][2]*=p[i];
        }//预处理所有数的分解
        
        int T,n,m;
        scanf("%d",&T);
        while (T--){
          scanf("%d%d",&n,&m);
          U ans=0;
          for (int i=0;i<n;i++) scanf("%d",&a[i]);
          for (int i=0;i<m;i++) scanf("%d",&bb[i]);
          for (int i=0;i<n;i++)
            for (int j=0;j<m;j++)
              ans+=gcd(a[i],bb[j])^i^j;
          printf("%u
    ",ans);
        }
      }

    BZOJ4454

  • 相关阅读:
    CSS
    网络通信
    模块与包
    python异常处理
    python基础考试一整理
    面向对象最后进阶
    面向对象-反射和__getattr__系列
    property、staticmethod和classmethod
    多态和封装
    scala构造器实战
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/6279431.html
Copyright © 2020-2023  润新知