1. 程式人生 > >[Luogu3932] 浮遊大陸的68號島

[Luogu3932] 浮遊大陸的68號島

格式 copy 答案 .cn mda bottom 密碼 會有 tin

題目背景

大樣例下發鏈接: https://pan.baidu.com/s/1nuVpRS1 密碼: sfxg

浮遊大陸的68號島,位於浮遊大陸的邊境地帶。平時很少有人造訪。

島上被濃厚的森林覆蓋。

技術分享圖片

在這座邊境地區不起眼的浮遊島上,建立著神秘的”兵器“管理倉庫——妖精倉庫。

題目描述

妖精倉庫裏生活著黃金妖精們,她們過著快樂,卻隨時準備著迎接死亡的生活。

換用更高尚的說法,是隨時準備著為這個無藥可救的世界獻身。

然而孩子們的生活卻總是無憂無慮的,幼體的黃金妖精們過著天真爛漫的生活,自然也無暇考慮什麽拯救世界之類的重任。

技術分享圖片

有一天小妖精們又在做遊戲。這個遊戲是這樣的。

妖精倉庫的儲物點可以看做在一個數軸上。每一個儲物點會有一些東西,同時他們之間存在距離。

每次他們會選出一個小妖精,然後剩下的人找到區間[l,r][l,r][l,r]儲物點的所有東西,清點完畢之後問她,把這個區間內所有儲物點的東西運到另外一個倉庫的代價是多少?

比如儲物點iii有xxx個東西,要運到儲物點jjj,代價為

x×dist(i,j)x \times \mathrm{dist}( i , j )x×dist(i,j)

dist就是倉庫間的距離。

當然啦,由於小妖精們不會算很大的數字,因此您的答案需要對19260817取模。

技術分享圖片

輸入輸出格式

輸入格式:

第一行兩個數表示n,mn,mn,m

第二行n−1n-1n1個數,第iii個數表示第iii個儲物點與第i+1i+1i+1個儲物點的距離

第三行nnn個數,表示每個儲物點的東西個數

之後mmm行每行三個數x l r

表示查詢要把區間[l,r][l,r][l,r]儲物點的物品全部運到儲物點x的花費

輸出格式:

對於每個詢問輸出一個數表示答案

輸入輸出樣例

輸入樣例#1: 復制
5 5
2 3 4 5
1 2 3 4 5
1 1 5
3 1 5
2 3 3
3 3 3
1 5 5
輸出樣例#1:
復制
125
72
9
0
70

說明

對於30%的數據,n,m≤1000n , m \le 1000n,m1000

對於另外20%的數據,所有儲物點間的距離都為1

對於另外20%的數據,所有儲物點的物品數都為1

對於100%的數據 ,n,m≤200000;ai,bi<=2⋅109 n , m \le 200000 ; a_i , b_i <= 2\cdot 10^9n,m200000;ai?,bi?<=2109


前綴和的應用。

比如我們要求$x$左邊的貢獻。

$\large ans=\sum|d[x]-d[i]|*a[i]$

$\large =\sum d[x]*a[i]-d[i]*a[i]$

$\large =d[x]*\sum a[i]-\sum d[i]*a[i]$

$x$右邊的同理。

所以我們可以計算$\large \sum a[i]$和$\large \sum d[i]*a[i]$就行了。


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
#define reg register 
#define int long long
inline int read() {
    int res = 0;char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
    return res;
}
#define mod 19260817
#define N 200005
int n, m;
int sigmaA[N], sigmaDa[N];
int d[N], a[N];

signed main()
{
    n = read(), m = read();
    for (reg int i = 2 ; i <= n ; i ++) 
    {
        d[i] = read();
        d[i] = (d[i] + d[i-1]) % mod;
    }
    for (reg int i = 1 ; i <= n ; i ++) 
    {
        a[i] = read();
        sigmaA[i] = (sigmaA[i-1] + a[i]) % mod;
        sigmaDa[i] = (sigmaDa[i-1] + d[i] * a[i] % mod) % mod;
    }
    while(m--)
    {
        int x = read(), l = read(), r = read();
        int ans = 0;
        if (x < l) {
            ans = -d[x] * (sigmaA[r] - sigmaA[l-1]) % mod + (sigmaDa[r] - sigmaDa[l-1]);
            printf("%lld\n", (ans % mod + mod) % mod);
            continue;
        }
        if (x > r)  {
            ans = d[x] * (sigmaA[r] - sigmaA[l-1]) % mod - (sigmaDa[r] - sigmaDa[l-1]);
            printf("%lld\n", (ans % mod + mod) % mod);
            continue;
        }
        ans = d[x] * (sigmaA[x] - sigmaA[l-1]) % mod - (sigmaDa[x] - sigmaDa[l-1]);
        ans = (ans + (-d[x] * (sigmaA[r] - sigmaA[x]) % mod + (sigmaDa[r] - sigmaDa[x])) % mod) % mod;
        printf("%lld\n", (ans % mod + mod) % mod);
    }
    return 0;
}

[Luogu3932] 浮遊大陸的68號島