jzoj6384. [2019.10.23] Ke scientists simulated NOIP2019

Description

Here Insert Picture Description

Input

Here Insert Picture Description

Output

The output common lines, each line represents a non-negative integer answers.

Sample Input

2 1
1 2 3
2 1 3
5

Sample Output

4

Only use reagent 1 and reagent 2 with drinks. There are two methods with an amount of 2,3 and 3,2, respectively, with each of tasty method is 2, the answer is 4.

Data Constraint

Here Insert Picture Description

Competitions

A two began to think a heap to maintain the practice.
Suddenly I found that it seems to take a log to make life difficult.
Painting persimmon can suddenly discover the difference.
Hastily finished, with two bell.
Finally, the T.

answer

Consider the difference.
First, choose an enumeration each case, a total of \ (n ^ 2 \) species.
Then for each factor we discuss it.
Probably long like this:
Here Insert Picture Description
So, we need only consider the differential divided into three segments.
First, the first increment, then equal, and finally it is decreasing.
Directly after the prefix and the difference can be made twice.
Note that constant, slightly optimize it.

Standard process

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const long long mo=998244353;
const int maxn=5010;
const int maxm=500010;
const int farr=20000010;

int n,m,tot;
long long a[maxn],l[maxn],r[maxn],q[maxm],sum[farr],ans[maxm];
long long val[maxn*maxn/2],zx[maxn*maxn/2],zd[maxn*maxn/2];

 __attribute__((optimize("-O3")))
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    {
        scanf("%lld%lld%lld",&a[i],&l[i],&r[i]);
    }
    int gs=0;
    for (int i=1;i<=n;i++)
    {
        for (int j=i+1;j<=n;j++)
        {
            gs++;
            val[gs]=a[i]*a[j]%mo;
            zx[gs]=l[i]+l[j];
            zd[gs]=r[i]+r[j];
            
            int mid=(zx[gs]+zd[gs])/2;
            int yd=(mid-zx[gs]+1)-min(r[i]-l[i]+1,r[j]-l[j]+1);
            if ((zd[gs]-zx[gs]+1)%2==1)
            {
                sum[zx[gs]]=sum[zx[gs]]+val[gs];
                if (sum[zx[gs]]>10000000000000000) sum[zx[gs]]%=mo;
                sum[mid+1-yd]=(sum[mid+1-yd]-val[gs]+mo);
                if (sum[mid+1-yd]>10000000000000000) sum[mid+1-yd]%=mo;
                sum[mid+1+yd]=(sum[mid+1+yd]-val[gs]+mo);
                if (sum[mid+1+yd]>10000000000000000) sum[mid+1+yd]%=mo;
                sum[zd[gs]+2]=(sum[zd[gs]+2]+val[gs]);
                if (sum[zd[gs]+2]>10000000000000000) sum[zd[gs]+2]%=mo;
            }
            else
            {
                sum[zx[gs]]=sum[zx[gs]]+val[gs];
                if (sum[zx[gs]]>10000000000000000) sum[zx[gs]]%=mo;
                sum[mid+1-yd]=(sum[mid+1-yd]-val[gs]+mo);
                if (sum[mid+1-yd]>10000000000000000) sum[mid+1-yd]%=mo;
                sum[mid+2+yd]=(sum[mid+2+yd]-val[gs]+mo);
                if (sum[mid+2+yd]>10000000000000000) sum[mid+2+yd]%=mo;
                sum[zd[gs]+2]=(sum[zd[gs]+2]+val[gs]);
                if (sum[zd[gs]+2]>10000000000000000) sum[zd[gs]+2]%=mo;
            }
        }
    }
    for (int i=1;i<=farr-1;i++)
    {
        sum[i]=(sum[i-1]+sum[i]+mo)%mo;
    }
    for (int i=1;i<=farr-1;i++)
    {
        ans[i]=(ans[i-1]+sum[i]+mo)%mo;
    }
    for (int i=1;i<=m;i++)
    {
        scanf("%lld",&q[i]);
    }
    for (int i=1;i<=m;i++)
    {
        printf("%lld\n",ans[q[i]]);
    }
}

Guess you like

Origin www.cnblogs.com/RainbowCrown/p/11731477.html