[洛谷P3962]浮游大陆的68号岛
2017-10-21 19:43
411 查看
题目←
两次前缀和来解决,式子并不难推
将二次前缀想像成三角形会比较好理解
需维护:
1、距离前缀;
2、总价值(运费)前后缀;
3、个数前后缀;
具体式子详见代码
比较恶心的是取模意义下随时会有负数,并不太会处理,求大佬指教:
qz、hz中的1表示运费,2表示个数
两次前缀和来解决,式子并不难推
将二次前缀想像成三角形会比较好理解
需维护:
1、距离前缀;
2、总价值(运费)前后缀;
3、个数前后缀;
具体式子详见代码
比较恶心的是取模意义下随时会有负数,并不太会处理,求大佬指教:
qz、hz中的1表示运费,2表示个数
#include<iostream> #include<cstdio> #include<algorithm> #define LL long long #define P 19260817 using namespace std; const int MAXN = 200000 + 50; LL qz1[MAXN],qz2[MAXN],hz1[MAXN],hz2[MAXN]; LL num[MAXN],dis[MAXN],ju[MAXN]; LL n,x,tot,m; int l,r,v; int main(){ scanf("%lld%lld",&n,&m); for(int i = 2;i <= n;i ++){ scanf("%lld",&ju[i]); dis[i] = (dis[i - 1]%P + ju[i]%P)%P; } for(int i = 1;i <= n;i ++){ scanf("%lld",&num[i]); qz1[i] = (qz1[i - 1]%P + (tot%P*ju[i]%P)%P)%P; tot = (num[i]%P + tot%P)%P; qz2[i] = tot; } tot = 0; for(int i = n;i >= 1;i --){ hz1[i] = (hz1[i + 1]%P + (tot%P*ju[i + 1]%P)%P)%P; tot = (num[i]%P + tot%P)%P; hz2[i] = tot; } /*for(int i = 1;i <= n;i ++){ printf("%lld ",hz1[i]); }*/ for(int i = 1;i <= m;i ++){ scanf("%d%d%d",&v,&l,&r); LL ans = 0; if(v >= l && v <= r){ LL temp1 = qz1[v] - qz1[l]; while(temp1 < 0)temp1 += P; LL tmp = dis[v] - dis[l]; while(tmp < 0)tmp += P; temp1 = (temp1 - qz2[l - 1]%P*(tmp%P))%P; while(temp1 < 0)temp1 += P; while(tmp < 0)tmp += P; LL temp2 = hz1[v] - hz1[r]; while(temp2 < 0)temp2 += P; tmp = dis[r] - dis[v]; while(tmp < 0)tmp += P; temp2 = (temp2 - hz2[r + 1]%P*(tmp%P))%P; while(temp2 < 0)temp2 += P; ans = (temp1%P + temp2%P)%P; } else if(v > r){ LL tmp = dis[r] - dis[l]; while(tmp < 0)tmp += P; LL tmp2 = qz1[r] - qz1[l]; while(tmp2 < 0)tmp2 += P; LL temp1 = tmp2 - (qz2[l - 1]%P*tmp)%P; while(temp1 < 0)temp1 += P; tmp = dis[v] - dis[r]; while(tmp < 0)tmp += P; tmp2 = qz2[r] - qz2[l - 1]; while(tmp2 < 0)tmp2 += P; temp1 = (temp1 + (tmp2*tmp)%P)%P; ans = temp1; } else if(v < l){ LL tmp = dis[r] - dis[l]; while(tmp < 0)tmp += P; LL tmp2 = hz1[l] - hz1[r]; while(tmp2 < 0)tmp2 += P; LL temp1 = tmp2 - (hz2[r + 1]*(dis[r] - dis[l])%P)%P; while(temp1 < 0)temp1 += P; tmp = dis[l] - dis[v]; while(tmp < 0)tmp += P; tmp2 = hz2[l] - hz2[r + 1]; while(tmp2 < 0)tmp2 += P; temp1 = (temp1 + (tmp2*tmp)%P)%P; ans = temp1; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- 洛谷3932:浮游大陆的68号岛——题解
- 洛谷10月月赛R2-T1-浮游大陆的68号岛
- 洛谷 3932 浮游大陆的68号岛 前缀和
- 线段树 洛谷P3932 浮游大陆的68号岛
- P3932 浮游大陆的68号岛 【线段树】
- noip模拟赛 浮游大陆的68号岛
- Luogu 3932(公式推导)(浮游大陆的68号岛)
- [luogu3932] 浮游大陆的68号岛
- 浮游大陆的68号岛
- 洛谷P3932 浮游大陆的68号岛
- P3932 浮游大陆的68号岛 【线段树】
- AC日记——贪婪大陆 洛谷 P2184
- 洛谷 P2184 贪婪大陆( 树状数组的活用 )
- 洛谷P2066 机器分配
- BZOJ1052: [HAOI2007]覆盖问题(洛谷P2218)
- 垃圾陷阱 洛谷1156 dp
- 洛谷-P1090 合并果子
- bzoj1304&&洛谷3155,树形DP
- 洛谷1251:[网络流24题]餐巾计划问题——题解
- 洛谷P1192 台阶问题