zoukankan      html  css  js  c++  java
  • luogu P3704 [SDOI2017]数字表格

    传送门

    我是真的弱,推式子只能推一半

    下面假设(n<m)

    考虑题目要求的东西,可以考虑每个gcd的贡献,即$$prod_{d=1}{n}f[d]{sum_{i=1}{lfloorfrac{n}{d} floor}sum_{j=1}{lfloorfrac{m}{d} floor}[gcd(i,j)=1]}$$

    (n=sum_{d|n} mu[d]),得$$prod_{d=1}{n}f[d]{sum_{i=1}{lfloorfrac{n}{d} floor}sum_{j=1}{lfloorfrac{m}{d} floor}sum_{k|i,k|j}mu[k]}$$$$prod_{d=1}{n}f[d]{sum_{k=1}^{lfloorfrac{n}{d} floor}mu[k]lfloorfrac{n}{kd} floorlfloorfrac{m}{kd} floor}$$

    大力数论分块即可获得60'好成绩

    如果我们令(t=kd),然后把t提出来,即则$$prod_{t=1}{n}prod_{d|t}f[d]{lfloorfrac{n}{t} floorlfloorfrac{m}{t} floormu[lfloorfrac{n}{d} floor]}$$$$prod_{t=1}{n}(prod_{d|t}f[d]{mu[lfloorfrac{n}{d} floor]})^{lfloorfrac{n}{t} floorlfloorfrac{m}{t} floor}$$

    里面的可以枚举每个数倍数预处理,然后就是数论分块

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define LL long long
    #define ldb long double
    #define il inline
    #define re register
    
    using namespace std;
    const int N=1e6+10,mod=1e9+7;
    il int rd()
    {
      int x=0,w=1;char ch=0;
      while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
      while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
      return x*w;
    }
    il int fpow(int a,int b){int an=1;while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;}return an;}
    bool v[N];
    int prm[N],mu[N],tt,fb[N],ifb[N],f[N],ivf[N];
    
    int main()
    {
      fb[0]=0,fb[1]=1,ifb[0]=ifb[1]=1;
      for(int i=2;i<=N-10;++i) fb[i]=(fb[i-1]+fb[i-2])%mod,ifb[i]=fpow(fb[i],mod-2);
      mu[1]=1;
      for(int i=2;i<=N-10;++i)
        {
          if(!v[i]) v[i]=1,prm[++tt]=i,mu[i]=-1;
          for(int j=1;j<=tt&&i*prm[j]<=N-10;++j)
            {
              v[i*prm[j]]=1,mu[i*prm[j]]=-mu[i];
              if(i%prm[j]==0) {mu[i*prm[j]]=0;break;}
            }
        }
      for(int i=0;i<=N-10;++i) f[i]=1;
      for(int i=1;i<=N-10;++i)
        for(int j=1;i*j<=N-10;++j)
          f[i*j]=1ll*f[i*j]*((~mu[j])?fpow(fb[i],mu[j]):ifb[i])%mod;
      ivf[0]=1;
      for(int i=1;i<=N-10;++i) f[i]=1ll*f[i]*f[i-1]%mod,ivf[i]=fpow(f[i],mod-2);
      int T=rd();
      while(T--)
        {
          int n=rd(),m=rd(),ans=1;
          if(n>m) swap(n,m);
          for(int i=1,j;i<=n;i=j+1)
            {
              j=min(n/(n/i),m/(m/i));
              ans=1ll*ans*fpow(1ll*f[j]*ivf[i-1]%mod,1ll*(m/i)*(n/i)%(mod-1))%mod;
            }
          printf("%d
    ",ans);
        }
      return 0;
    }
    
  • 相关阅读:
    如何解决快应用堆栈溢出问题
    华为携手Work Shift Calendar (Shifter),将工作效率提升至更高水平
    教你如何实现长按图片保存到相册
    【DTM】HUAWEI Ads与DTM网页转化追踪(二)
    map组件如何展示marker的callout气泡
    【DTM】HUAWEI Ads与DTM网页转化追踪(一)
    “碰一碰”版本的蓝牙键盘,来啦!
    ES-密码设置及JAVA应用
    ES--集群搭建及原理
    ES--ELK搭建(ElasticSearch、Logstash、Kibana)
  • 原文地址:https://www.cnblogs.com/smyjr/p/10152912.html
Copyright © 2011-2022 走看看