洛谷 P3932 浮游大陆的68号岛 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P3932 浮游大陆的68号岛 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:https://www.luogu.org/problem/show?pid=P3932

题目描述

有一天小妖精们在做游戏。这个游戏是这样的。

妖精仓库的储物点可以看做在一个数轴上。每一个储物点会有一些东西,同时他们之间存在距离。

每次他们会选出一个小妖精,然后剩下的人找到区间[l,r]储物点的所有东西,清点完毕之后问她,把这个区间内所有储物点的东西运到另外一个仓库的代价是多少?

比如储物点ix个东西,要运到储物点j,代价为x*dist(i,j)

dist就是仓库间的距离。

当然啦,由于小妖精们不会算很大的数字,因此您的答案需要对19260817取模。

输入输出格式

输入格式:

第一行两个数表示n,m

第二行n−1个数,第i个数表示第i个储物点与第i+1个储物点的距离

第三行n个数,表示每个储物点的东西个数

之后m行每行三个数x 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≤1000

对于另外20%的数据,所有储物点间的距离都为1

对于另外20%的数据,所有储物点的物品数都为1

对于100%的数据 ,n,m≤200000;ai,bi<=2⋅10^9

 

分析:

话说月赛题解就讲得很清楚了,所以分析不写了吧

(还是要说一下的)

直接暴力求显然只能拿30分。

设区间内每个仓库的物品数为a,坐标为b,目标仓库坐标x,对于每次询问,可以分三种情况:

1.仓库在区间的右边,此时的花费=a1*(x-b1)+a2*(x-b2)+a3*(x-b3)*...*an*(x-bn)=x*∑ai - ∑ai*bi

2.仓库在区间的左边,此时的花费=a1*(b1-x)+a2*(b2-x)+a3*(b3-x)*...*an*(bn-x)= - (x*∑ai - ∑ai*bi)

3.仓库在区间内,此时把区间分为左右两部分,然后对应按照1.2.计算,再加起来。

请把所有能取模的地方都加上取模,多一个MOD,少一个TLE(亲测qwq)。

 

AC代码:

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 
 7 const long long MOD = 19260817;
 8 const int MAXN = 200002;
 9 inline void read(long long &x)
10 {
11     char ch = getchar(),c = ch;x = 0;
12     while(ch < 0 || ch > 9) c = ch,ch = getchar();
13     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
14     if(c == -) x = -x;
15 }
16 
17 long long n,m,ans,x,l,r;
18 long long num[MAXN],prcalc[MAXN],dist[MAXN],pre[MAXN];
19 
20 
21 int main()
22 {
23     read(n),read(m);
24     for(int i = 2;i <= n;++ i){
25         read(dist[i]);
26         dist[i] = (dist[i]+dist[i-1])%MOD;
27     }
28     for(int i = 1;i <= n;++ i){
29         read(num[i]);
30         pre[i] = (pre[i-1]+num[i])%MOD;
31     }
32     for(int i = 1;i <= n;++ i)
33         prcalc[i] = (prcalc[i-1]+dist[i]*num[i])%MOD;
34 
35     for(int i = 1;i <= m;++ i)
36     {
37         read(x),read(l),read(r);
38         ans = 0;
39         if(x >= r)
40             ans = dist[x]*(pre[r]-pre[l-1])%MOD - (prcalc[r]-prcalc[l-1]);
41         else if(x <= l)
42             ans = (prcalc[r]-prcalc[l-1]) - dist[x]*(pre[r]-pre[l-1])%MOD;
43         else if(l < x && x < r)
44         {
45             ans = ((prcalc[r]-prcalc[x]) - dist[x]*(pre[r]-pre[x]))%MOD;
46             ans += (dist[x]*(pre[x-1]-pre[l-1]) - (prcalc[x-1]-prcalc[l-1]))%MOD;
47         }
48         while(ans < 0) ans += MOD;
49         printf("%lld\n",ans%MOD);
50     }
51     
52     return 0;
53 }

 

以上是关于洛谷 P3932 浮游大陆的68号岛 题解的主要内容,如果未能解决你的问题,请参考以下文章

[洛谷P3932]浮游大陆的68号岛

P3932 浮游大陆的68号岛

P3932 浮游大陆的68号岛

luogu P3932 浮游大陆的68号岛

[Luogu3932] 浮游大陆的68号岛

洛谷 2184 贪婪大陆