「不知道该说什么题」[Codeforces 1017F] The Neutral Zone
首先要有个 Observation,大概就是说可以发现对于每个质数的幂次
大概是说可以考虑每个质因数产生的贡献,彼此之间是线性无关的 ,所以可以分别考虑每个质数幂的贡献。具体的,我们只需要求出所有的质数以及质数的幂对答案的贡献就好了,这部分为了卡空间可以用埃氏筛。
但是发现还是过不去。因为埃氏筛的复杂度太高了。不过仔细分析一波,发现慢在诸如
但是发现这样空间还是会有点问题。于是可以用 bitset + 合并状态来压缩。合并状态的原理是刨除了所有
个人觉得这题能放到 F,唯一的原因就是因为需要十分优秀的卡常 and 卡空间技术。
#include <bitset>
#include <cstdio>
const int N = 100000005 ;
using std :: bitset ;
typedef long long ll ;
typedef unsigned int lint ;
int n ;
bitset <N> vis ;
int A, B, C, D ;
lint ans ;
inline bool chk(int x){
return ((!(x & 1)) || (x % 3 == 0) || (x % 5 == 0)) ;
}
lint calc(int p){
return 1u * A * p * p * p + 1u * B * p * p + 1u * C * p + D ;
}
lint solve(int p){
lint ret = 0, v = calc(p) ;
for (ll x = p ; x <= n ; x *= p)
ret += 1u * (n / x) * v ; return ret ;
}
int main(){
scanf("%d", &n) ; ans = 0 ;
scanf("%d%d%d%d", &A, &B, &C, &D) ;
if (n >= 2) ans += solve(2) ;
if (n >= 3) ans += solve(3) ;
if (n >= 5) ans += solve(5) ;
for (int i = 7 ; i <= n ; ++ i){
if (chk(i)) continue ;
if (vis[i / 3]) continue ; ans += solve(i) ; //printf("%u\n", ans) ;
for (int j = i + i ; j <= n ; j += i)
if (!chk(j)) vis[j / 3] = 1 ;
}
printf("%u\n", ans) ; return 0 ;
}