Counting Divisors HDU - 6069 多校#4 因数分解算贡献

#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
using namespace std;
#define ll long long
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
const int inf=0x3f3f3f3f;
const int maxn=1e6+9; 
const int mod=998244353;

int tot;
bool vis[maxn];
ll prime[maxn];
void init(){
	tot=0;
	for(int i=2;i<maxn;i++){
		if(!vis[i]){
			prime[tot++]=i;
			for(int j=i+i;j<maxn;j+=i)vis[j]=1;
		}
	}
}

ll sum[maxn],num[maxn];
int main(){
	init();
	int T;scanf("%d",&T);while(T--){
		ll ans=0;
		ll l,r,k;scanf("%lld%lld%lld",&l,&r,&k);
		for(int i=0;i<=r-l;i++){sum[i]=1;num[i]=i+l;}
		for(int i=0;prime[i]*prime[i]<=r;i++){
			for(ll j=(l/prime[i]+(l%prime[i]?1:0))*prime[i];j<=r;j+=prime[i]){
				ll res=0;
				while(num[j-l]%prime[i]==0){
					num[j-l]/=prime[i];
					res++;
				}
				sum[j-l]=sum[j-l]*(res*k+1)%mod;
			}
		}
		for(int i=0;i<=r-l;i++){
			if(num[i]>1)sum[i]=sum[i]*(k+1)%mod;
			ans=(ans+sum[i])%mod;
		}
		printf("%lld\n",ans);
	}
}

这种写法比我瞎搞的好多了。。另开一个数组num表示l到r中的每一个

对于枚举的因数直接在num暴力除掉,区间内素数最后就不是1

其他没啥了,注意一下乘法和加法的运用就好

posted @ 2017-08-15 21:39  Drenight  阅读(142)  评论(0编辑  收藏  举报