[Project Euler 603]Substring sums of prime concatenations 题解
傻逼题,倍增合并,考虑跨过中间部分的答案,算起来细节有点烦,写挂了一小部分调了2个多小时……
//waz #include <bits/stdc++.h> 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<int, int> PII; typedef vector<int> 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 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; } struct item { int sum; int lsum, rsum; int ans; int p1, p2; friend item operator + (item a, item b) { item c; c.p1 = inc(a.p1, b.p1); c.p2 = (a.p2 + b.p2) % (mod - 1); c.ans = inc(a.ans, b.ans); int s = 1LL * (fpow(10, b.p2) - 1LL) * fpow(9, mod - 2) % mod * 10LL % mod; c.ans = inc(c.ans, 1LL * a.rsum * s % mod); c.ans = inc(c.ans, 1LL * b.lsum * a.p1 % mod); c.sum = (1LL * a.sum * fpow(10, b.p2) + b.sum) % mod; c.rsum = inc(1LL * a.rsum * fpow(10, b.p2) % mod, (b.rsum + 1LL * b.sum * a.p1) % mod); c.lsum = inc(inc(10LL * a.sum % mod * (fpow(10, b.p2) - 1) % mod * fpow(9, mod - 2) % mod, a.lsum), b.lsum); return c; } void init(int x) { sum = lsum = rsum = ans = x; p1 = p2 = 1; } }; item t; void ins(item &t, int x) { item c; c.init(x); t = t + c; //putchar(x + '0'); } item power(item x, long long m) { item c = (item) {0, 0, 0, 0, 0, 0}; for (; m; m >>= 1) { if (m & 1) c = c + x; x = x + x; } return c; } const int N = 1e8 + 10; bitset<N> fg; int n; long long m; int main() { n = 1e6, m = 1e12; for (int i = 2, nn = 2 * 1e7; i <= nn; ++i) { if (!fg[i]) { for (int j = i + i; j <= nn; j += i) fg[j] = 1; int j = i; static int stk[233]; int tp = 0; while (j) { stk[++tp] = j % 10; j /= 10; } while (tp) ins(t, stk[tp--]); --n; if (!n) { //cerr << i << endl; break; } } } printf("%d\n", power(t, m).ans); }