2018南京区域赛 J-Prime Game

完全没有头绪
听完队友讲的我还是楞了好半天菜慢慢理解.我好菜啊
首先要弄懂题目的意思,转换一下题意就是求每个素因子出现区间的次数.区间长度最短为1.我们分析,第一个数的因子会影响1* n个区间(暂时不考虑重复),第二个数的因子会影响2 * (n-1)个区间,以此类推.因此我们只需要分解每一个数然后加上影响的区间即可.

我们从前往后处理.

可是很容易重复,问题就在于我们如何处理重复的因子.对于位置 i i i的因子 x x x,假设在位置 j j j已经出现过,那么对于 [ j , i − 1 ] [j,i-1] [j,i1]的区间是没有影响的,可是对于以 [ 1 , j ] [1,j] [1,j]开头的区间和以 [ i , n ] [i,n] [i,n]结尾的区间这个因子就会重复计数,因此为了消去重复,我们给答案减去 j ∗ ( n − i + 1 ) j*(n-i+1) j(ni+1),即会影响区间的个数.对于后面再出现因子 x x x的时候,因为 j j j对后面的影响已经消去,我们只需要考虑 i i i对后面的影响,所以同样进行操作就可以,因此我们记住因子最后出现的位置然后计算即可.

需要注意分解质因数的时候只需要处理到这个数字的开方就可以,如果这个时候这个数还不为1就说明剩下的一定是一个质数就不要进行处理了,否则会超时.

记得开long long ,而且要注意中间会爆long long ,所以在更新ans的时候要小心.

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<cctype>
#include<queue>
#include<set>
#include<cmath>

using namespace std;

typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e6+5;
const int MAXM=1e6+5;

int check[MAXM];
int prime[MAXM];
int vis[MAXM];
int tot=0;
int n,x;
ll ans;

void creat_prime()
{
	for(int i=2;i<MAXN;i++)
	{
		if(!check[i]) prime[tot++]=i;
		for(int j=0;j<tot && prime[j]*i<MAXN;j++)
		{
			check[prime[j]*i]=true;
			if(i%prime[j]==0) break;
		}
	}
}

void deal(int x,int idx)
{
	
	int t=sqrt(x)+1;
	
	for(int i=0;i<tot && prime[i]<=t;i++)
	{
		if(x%prime[i]==0)
		{
			ans+=(ll)idx*(n-idx+1);
			if(vis[prime[i]]==0) vis[prime[i]]=idx;
			else
			{
				ans-=(ll)vis[prime[i]]*(n-idx+1);
				vis[prime[i]]=idx;
			}
			while(x%prime[i]==0)
			{
				x/=prime[i];
			}
		}
		if(x==1) break;
	}
	if(x>1)
	{
		ans+=(ll)idx*(n-idx+1);
		if(vis[x]==0) vis[x]=idx;
		else
		{
			ans-=(ll)vis[x]*(n-idx+1);
			vis[x]=idx;
		}
	}
}

int main()
{
	creat_prime();
	scanf("%d",&n);
	ans=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		deal(x,i);
	}
	printf("%lld\n",ans);
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值