zoukankan      html  css  js  c++  java
  • [NOI2016]循环之美

    题解

    神仙。

    考虑这个循环小数的循环节为(l)

    那么有

    [frac{x}{y}-leftlfloordfrac{x}{y} ight floor=frac{xk^l}{y}-leftlfloordfrac{xk^l}{y} ight floor ]

    [x-leftlfloordfrac{x}{y} ight floor*y=xk^l-leftlfloordfrac{xk^l}{y} ight floor*y ]

    [x=xk^l mod y ]

    [k^l=1 mod y ]

    根据数论知识可得((k,y)==1)

    然后我们设(f(n,m,k))表示答案。

    [f(n,m,k)=sum_{i=1}^nsum_{j=1}^m [(i,j)==1][(j,k)==1] ]

    [sum_{i=1}^nsum_{j=1}^m[(i,j)==1]sum_{d|(j,k)}mu(d) ]

    [sum_{i=1}^nsum_{jd=1}^m[(i,jd)==1]sum_{d|k}mu(d) ]

    [sum_{d|k}mu(d)sum_{i=1}^nsum_{j=1}^{frac{m}{d}}(i,jd)==1 ]

    [sum_{d|k}mu(d)sum_{i=1}^nsum_{j=1}^{frac{m}{d}}[(i,j)==1][(i,d)==1] ]

    [sum_{d|k}mu(d)f(frac{m}{d},n,d) ]

    然后就可以做了。

    注意边界:(m)或n为(0)时值为(0),当(d=1)的时候就除法分块一下。

    代码

    #include<bits/stdc++.h>
    #define N 6000009
    using namespace std;
    typedef long long ll;
    const int maxn=6000000;
    vector<int>vec[2002];
    bool vis[N];
    int prime[N],mu[N],n,m,k;
    inline ll rd(){
      ll x=0;char c=getchar();bool f=0;
      while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
      while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
      return f?-x:x;
    }
    struct node{
      int n,m,k;
      inline bool operator <(const node &b)const{
        if(n!=b.n)return n<b.n;
        if(m!=b.m)return m<b.m;
        if(k!=b.k)return k<b.k;
      }
    };
    map<node,ll>mp;
    map<int,int>rec;
    inline void prework(int n){
      mu[1]=1;
      for(int i=2;i<=n;++i){
        if(!vis[i]){prime[++prime[0]]=i;mu[i]=-1;}
        for(int j=1;j<=prime[0]&&(i*prime[j])<=maxn;++j){
          vis[i*prime[j]]=1;
          if(i%prime[j]==0){
             mu[i*prime[j]]=0;
             break;
          }
          mu[i*prime[j]]=-mu[i];
        }
      }
      for(int i=1;i<=n;++i)mu[i]+=mu[i-1];
    }
    inline int getsum(int n){
      if(n<=maxn)return mu[n];
      if(rec.find(n)!=rec.end())return rec[n];
      int ans=1;ll r=0;
      for(int l=2;l<=n;l=r+1){
        r=n/(n/l);
        ans-=(r-l+1)*getsum(n/l);
      }
      return rec[n]=ans;
    }
    inline ll work(int n,int m,int k){
      if(!n||!m)return 0;
      node x=node{n,m,k};
      if(mp.find(x)!=mp.end())return mp[x];
      ll ans=0;
      if(k==1){
        ll r=0;int x=min(n,m);
        for(ll l=1;l<=x;l=r+1){
          r=min(n/(n/l),m/(m/l));
          ans+=1ll*(getsum(r)-getsum(l-1))*(n/l)*(m/l);
        }
      }
      else{
        for(vector<int>::iterator it=vec[k].begin();it!=vec[k].end();++it){
          int v=*it;
          ans+=work(m/v,n,v)*(mu[v]-mu[v-1]);
          if(v>m)break;
        }
      }
      return mp[x]=ans;
    }
    int main(){
      n=rd();m=rd();k=rd();
      prework(maxn);
      for(int i=1;i<=k;++i)if(mu[i]-mu[i-1]!=0){
        int x=i;
        while(x<=k){
          vec[x].push_back(i);
          x+=i;
        }
      }
      printf("%lld",work(n,m,k));
      return 0;
    }
    
  • 相关阅读:
    系统改造/升级项目的注意点
    phpunit相关
    IE浏览器:定义文档兼容性
    pptx,docx,xlsx 文件下载问题
    常用linux命令
    oracle 子查询写法
    QQ上传大文件为什么这么快
    decimal tostring 格式
    2020HDU多校第三场 1005 Little W and Contest
    火车进栈(进出栈的模拟,dfs爆搜)
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10942656.html
Copyright © 2011-2022 走看看