洛谷 P3932 浮游大陆的68号岛 题解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P3932 浮游大陆的68号岛 题解相关的知识,希望对你有一定的参考价值。
此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。
题目链接:https://www.luogu.org/problem/show?pid=P3932
题目描述
有一天小妖精们在做游戏。这个游戏是这样的。
妖精仓库的储物点可以看做在一个数轴上。每一个储物点会有一些东西,同时他们之间存在距离。
每次他们会选出一个小妖精,然后剩下的人找到区间[l,r]储物点的所有东西,清点完毕之后问她,把这个区间内所有储物点的东西运到另外一个仓库的代价是多少?
比如储物点i有x个东西,要运到储物点j,代价为x*dist(i,j)
dist就是仓库间的距离。
当然啦,由于小妖精们不会算很大的数字,因此您的答案需要对19260817取模。
输入输出格式
输入格式:
第一行两个数表示n,m
第二行n−1个数,第i个数表示第i个储物点与第i+1个储物点的距离
第三行n个数,表示每个储物点的东西个数
之后m行每行三个数x l r
表示查询要把区间[l,r]储物点的物品全部运到储物点x的花费
输出格式:
对于每个询问输出一个数表示答案
输入输出样例
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
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号岛 题解的主要内容,如果未能解决你的问题,请参考以下文章