JZOJ6384【NOIP2019模拟2019.10.23】珂学家

珂学家

题目描述:
在这里插入图片描述
输入:
在这里插入图片描述
输出:
输出共 m m 行,每行一个非负整数表示答案。

这道题看到是一个区间,便想到了数据结构之类的东西。
但是呢它好像不带修。所以初步判断这是个离线的题目。
再仔细观察发现,这不就是差分数组吗?

首先显然 n n 不大,可以 O ( n 2 ) O(n^2) 来枚举每一种情况。
然后进行差分。但是好像很难搞。

所以我们先可以对标记进行差分,然后在差分一次。
对于两个试剂,差分:
t m p = tmp = 两种试剂的可口度的乘积。
1、 s u m [ l 1 + l 2 ] + t m p sum[l1+l2] + tmp
2、 s u m [ l 1 + r 2 1 ] t m p sum[l1+r2-1]-tmp
3、 s u m [ l 2 + r 1 1 ] t m p sum[l2+r1-1]-tmp
4、 s u m [ r 2 + r 1 + 2 ] + t m p sum[r2+r1+2]+tmp

然后跑前缀和就好了。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;

const ll mod = 998244353;
const ll N = 5010;

inline ll min(ll a,ll b) { return a < b ? a : b; }

inline ll max(ll a,ll b) { return a > b ? a : b; }

inline void read(ll &x)
{
    char ch = getchar(); x = 0;
    for(;ch < '0' || ch > '9';) ch = getchar();
    for(;ch >= '0' && ch <= '9';) x = x * 10 + (ch ^ '0'), ch = getchar();
}

struct node{ ll val,l,r; } p[N];
ll n,m,sum[N],mx;

int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);

    read(n), read(m); ++ m;
    for(int i = 1;i <= n; ++ i)
        read(p[i].val), read(p[i].l), read(p[i].r), mx = max(mx,p[i].r);
    
    for(int i = 1;i < n; ++ i)
        for(int j = i + 1;j <= n; ++ j)
        {
            ll lx = p[i].l,rx = p[i].r,ly = p[j].l,ry = p[j].r,tmp = p[i].val * p[j].val % mod;
            sum[lx + ly] = (sum[lx + ly] + tmp) % mod, sum[lx + ry + 1] = (sum[lx + ry + 1] - tmp) % mod;
            sum[rx + ly + 1] = (sum[rx + ly + 1] - tmp) % mod, sum[rx + ry + 2] = (sum[rx + ry + 2] + tmp) % mod;
        }

    for(int i = 1;i <= 2 * mx + 1; ++ i) sum[i] = (sum[i - 1] + sum[i]) % mod;
    for(int i = 1;i <= 2 * mx + 1; ++ i) sum[i] = (sum[i - 1] + sum[i]) % mod;

    for(ll x;--m;) read(x), printf("%lld\n",(sum[x] + mod) % mod); 

    // fclose(stdin); fclose(stdout);
    return 0;
}

考场数组开小了。 Q A Q QAQ 自闭了。。。

猜你喜欢

转载自blog.csdn.net/INnovate2030/article/details/102821931
今日推荐