P4828 Nagisa loves Tomoya

毒瘤月赛题,暴力没有分系列。。。

这道题不知道为什么,我打暴力应该是没问题的,用一个类似于莫队的思想来处理询问。然后就爆零了。。。

这道题的正解是这样的:

你模拟一下题意,就会发现一个神奇的系数问题。

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
......

这就是个yh三角咯。所以你可以\(O(2000^2)\)地打出整个杨辉三角,然后就可以很便捷地处理所有问题。

同时注意取膜即可。没事开long long保平安。

#include<cstdio>
#include<algorithm>
#define ll long long
const int maxn = 1000005;
const int p = 998244353;
struct Query
{
    ll x, y;
    bool operator < (const Query &rhs) const
    {
        return x < rhs.x;
    }
} s[10005];
ll yh[2001][2001];
ll n, m;
ll a[maxn];
void init(int bound)
{
    for(int i = 0; i <= bound; i++) yh[i][0] = 1;
    for(int i = 1; i <= bound; i++)
    {
        for(int j = 1; j <= i; j++)
        {
            yh[i][j] = (yh[i - 1][j] + yh[i - 1][j - 1]) % p;
        }
    }
    /*
    for(int i = 0; i <= 10; i++)
    {
        for(int j = 0; j <= i; j++)
        {
            printf("%d ", yh[i][j]);
        }
        printf("\n");
    }
    */
}
ll read()
{
    ll ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
    return s * ans;
}
ll solve(ll x, ll y)
{
    ll ans = 0;
    for(int i = y, j = 0; j <= x; i = i % n + 1, j++)
    {
        ans = (ans + yh[x][j] * a[i]) % p;
    }
    return ans % p;
}
int main()
{
    n = read();
    for(int i = 1; i <= n; i++) a[i] = read();
    m = read();
    for(int i = 1; i <= m; i++) s[i].x = read(), s[i].y = read();
    init(2000);
    //std::sort(s + 1, s + m + 1);
    for(int i = 1; i <= m; i++)
    {
        printf("%lld\n", solve(s[i].x, s[i].y));
    }
    return 0;
}
posted @ 2018-10-19 13:14  Garen-Wang  阅读(264)  评论(0编辑  收藏  举报