[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);
}

 

posted @ 2019-02-28 16:26  AnzheWang  阅读(199)  评论(0编辑  收藏  举报