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
其他没啥了,注意一下乘法和加法的运用就好