zoukankan      html  css  js  c++  java
  • Codeforces915G. Coprime Arrays

    n<=2e6的数组,m<=2e6个询问,对1<=i<=m的每个i问:只用<=i的数字填进数组,有多少种方案使数组的总gcd=1.强制把每个询问的答案求出来。

    比如说现在有个确定的i=t,然后看看答案怎么算先。先把所有情况加起来,然后除去gcd=2,3,4,5,……的,那直接统计有多少gcd=2,3,4,5的不方便,总可以统计有多少gcd是2的倍数的,3的倍数的,……,吧!这样的话丢掉了gcd为2的倍数,3的倍数的,等等6的倍数丢多了一次因为在2和3都算了,要减掉……就一个容斥,对应了各自的莫比乌斯函数。于是可以愉快的写出t的答案$f(t)=sum_{i=1}^{t} mu(i) (frac{t}{i})^n$。

    然后就看看t变成t+1时答案怎么变化,对一个k,他的$(frac{t}{k})$只有在t是k的倍数时才会变化!而这个“变化”的总数,就是1-m中所有1-m的倍数的数量的总数,就是m+m/2+m/3+……,就是mlnm个“变化”,就可以做!

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 //#include<assert.h>
     6 #include<algorithm> 
     7 //#include<iostream>
     8 //#include<bitset>
     9 using namespace std;
    10 
    11 int n,m;
    12 #define maxn 2000011
    13 const int mod=1e9+7;
    14 int miu[maxn],prime[maxn],lp=0,mi[maxn],small[maxn]; bool notprime[maxn];
    15 
    16 int powmod(int a,int b)
    17 {
    18     int ans=1;
    19     while (b)
    20     {
    21         if (b&1) ans=1ll*ans*a%mod;
    22         a=1ll*a*a%mod;
    23         b>>=1;
    24     }
    25     return ans;
    26 }
    27 
    28 void pre(int n)
    29 {
    30     miu[1]=1;
    31     for (int i=2;i<=n;i++)
    32     {
    33         if (!notprime[i]) {prime[++lp]=i; miu[i]=-1; small[i]=i;}
    34         for (int j=1;j<=lp && 1ll*prime[j]*i<=n;j++)
    35         {
    36             notprime[i*prime[j]]=1;
    37             small[i*prime[j]]=prime[j];
    38             if (i%prime[j]) miu[i*prime[j]]=-miu[i];
    39             else {miu[i*prime[j]]=0; break;}
    40         }
    41     }
    42 }
    43 
    44 int ans,fix,num[maxn];
    45 int list[maxn],ci[maxn],ll;
    46 void play(int x)
    47 {
    48     fix+=miu[x]*(mi[num[x]+1]-mi[num[x]]);
    49     fix+=fix<0?mod:0,fix-=fix>=mod?mod:0;
    50     num[x]++;
    51 }
    52 void dfs(int now,int cur)
    53 {
    54     if (cur>ll) {play(now); return;}
    55     for (int i=0,tmp=1;i<=ci[cur];i++,tmp*=list[cur]) dfs(now*tmp,cur+1);
    56 }
    57 
    58 void solve(int x)
    59 {
    60     ll=0;
    61     for (int i=x;i>1;i/=small[i])
    62     {
    63         if (list[ll]!=small[i]) list[++ll]=small[i],ci[ll]=1;
    64         else ci[ll]++;
    65     }
    66     dfs(1,1);
    67 }
    68     
    69 int main()
    70 {
    71     scanf("%d%d",&n,&m); pre(m);
    72     for (int i=1;i<=m;i++) mi[i]=powmod(i,n);
    73     
    74     ans=0; fix=0;
    75     for (int i=1;i<=m;i++) solve(i),ans+=i^fix,ans-=ans>=mod?mod:0;
    76     printf("%d
    ",ans);
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    ADF中遍历VO中的行数据(Iterator)
    程序中实现两个DataTable的Left Join效果(修改了,网上第二个DataTable为空,所处的异常)
    ArcGIS api for javascript——鼠标悬停时显示信息窗口
    ArcGIS api for javascript——查询,然后单击显示信息窗口
    ArcGIS api for javascript——查询,立刻打开信息窗口
    ArcGIS api for javascript——显示多个查询结果
    ArcGIS api for javascript——用图表显示查询结果
    ArcGIS api for javascript——查询没有地图的数据
    ArcGIS api for javascript——用第二个服务的范围设置地图范围
    ArcGIS api for javascript——显示地图属性
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8286735.html
Copyright © 2011-2022 走看看