当前位置: 代码迷 >> 综合 >> Gym 101981J Prime Game (组合计数)
  详细解决方案

Gym 101981J Prime Game (组合计数)

热度:54   发布时间:2023-11-15 13:51:00.0

题目链接:http://codeforces.com/gym/101981/attachments

#include<bits/stdc++.h>
using namespace std;#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll unsigned long long#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
const int  maxn =1e6+5;
const int mod=9999991;
const double e=2.71828;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
对每个质数,求出位置序列,
这样就可以对每个质数计算其对整体的贡献了,
假设质数x的序列是p1,p2,。。。pm,
只要组合计算左右区间端点出现的位置不重复计算该质数就可以了。
复杂度:O(nlogn)。
*/vector<int> p[maxn];///存放质数的位置
int n,x,ub;
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&x);ub=max(ub,x);for(int j=2;j*j<=x;j++)if(x%j==0){while(x%j==0) x/=j;p[j].push_back(i);}if(x>1) p[x].push_back(i);}ll ans=0;for(int i=2;i<=ub;i++) if(p[i].size()){///cout<<i<<" "<<p[i].size()<<endl;sort(p[i].begin(),p[i].end());for(int j=0;j<p[i].size();j++){if(j==0) ans+=1LL*p[i][j]*(n-p[i][j]+1);else ans+=1LL*(p[i][j]-p[i][j-1])*(n-p[i][j]+1);}}printf("%lld\n",ans);return 0;
}

 

  相关解决方案