博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LOJ#6053]简单的函数 题解
阅读量:4650 次
发布时间:2019-06-09

本文共 3583 字,大约阅读时间需要 11 分钟。

最近在搞min_25筛,就写几道筛法题吧

模板题,直接套板子就好了

//waz#include 
using namespace std;#define mp make_pair#define pb push_back#define fi first#define se second#define ALL(x) (x).begin(), (x).end()#define SZ(x) ((int)((x).size()))typedef pair
PII;typedef vector
VI;typedef long long int64;typedef unsigned int uint;typedef unsigned long long uint64;#define gi(x) ((x) = F())#define gii(x, y) (gi(x), gi(y))#define giii(x, y, z) (gii(x, y), gi(z))int F(){ char ch; int x, a; while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-'); if (ch == '-') ch = getchar(), a = -1; else a = 1; x = ch - '0'; while (ch = getchar(), ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + ch - '0'; return a * x;}const int mod = 1e9 + 7;int inc(int a, int b) { a += b; return a >= mod ? a - mod : a; }int dec(int a, int b) { a -= b; return a < 0 ? a + mod : a; }int fpow(int a, int x){ int ret = 1; for (; x; x >>= 1) { if (x & 1) ret = 1LL * ret * a % mod; a = 1LL * a * a % mod; } return ret;}const int N = 1e5 + 10;int64 n;int p[N], pt, sump[N], sumf[N];bool fg[N];int sqrtn;namespace work1{ int f1[N << 1], f2[N << 1]; int id1[N], id2[N], idt; int64 num[N << 1]; int id(int64 x) { if (x <= sqrtn) return id1[x]; else return id2[n / x]; } void solve() { idt = 0; for (int64 i = 1, j; i <= n; i = j + 1) { int64 t = n / i; j = n / t; if (t <= sqrtn) id1[t] = ++idt; else id2[n / t] = ++idt; num[idt] = t; int64 c = t % mod; f1[idt] = (c * (c + 1) / 2 + mod - 1) % mod; f2[idt] = c - 1; } for (int j = 1; j <= pt; ++j) { int64 end = 1LL * p[j] * p[j]; for (int k = 1; num[k] >= end; ++k) { int i = id(num[k] / p[j]); f1[k] = dec(f1[k], 1LL * dec(f1[i], sump[j - 1]) * p[j] % mod); f2[k] = dec(f2[k], 1LL * dec(f2[i], j - 1)); } } } int query(int64 x) { return inc(dec(f1[id(x)], f2[id(x)]), 2 * (x >= 2)); }}namespace work2{ int g[N << 1]; int id1[N], id2[N], idt; int64 num[N << 1]; int id(int64 x) { if (x <= sqrtn) return id1[x]; else return id2[n / x]; } int solve() { for (int64 i = 1, j; i <= n; i = j + 1) { int64 t = n / i; j = n / t; if (t <= sqrtn) id1[t] = ++idt; else id2[n / t] = ++idt; num[idt] = t; g[idt] = work1::query(t); } for (int j = pt; j; --j) { for (int k = 1; num[k] >= 1LL * p[j] * p[j]; ++k) { int i = 1; for (int64 m = p[j]; m * p[j] <= num[k]; ++i, m *= p[j]) { g[k] = inc(g[k], 1LL * dec(g[id(num[k] / m)], sumf[j]) * (p[j] ^ i) % mod); g[k] = inc(g[k], p[j] ^ (i + 1)); } } } return inc(g[id(n)], 1); }}int main(){ cin >> n; sqrtn = sqrt(n); for (int i = 2; i <= sqrtn; ++i) { if (!fg[i]) { p[++pt] = i; } for (int j = 1; j <= pt && p[j] * i <= sqrtn; ++j) { fg[p[j] * i] = 1; if (i % p[j] == 0) break; } } for (int i = 1; i <= pt; ++i) sump[i] = inc(sump[i - 1], p[i]), sumf[i] = inc(sumf[i - 1], p[i] ^ 1); work1::solve(); //cerr << work1::query(n) << endl; cout << work2::solve() << endl;}

 

转载于:https://www.cnblogs.com/AnzheWang/p/10453740.html

你可能感兴趣的文章