赛时

花了近2h来课这道题.
发现了贪心规律,本想着可以水水70分。
然鹅发现数据过大,似乎要打高精度?
心态崩了,最后连20分都没拿到。
后来才发现一个小小的性质,不用打高精度。
太菜了。

题解

首先我们画画柿子。
答案即为∑i=lrai∗2ki\sum_{i=l}^r a_i*2^{k_i}∑i=lr​ai​∗2ki​
其中可以控制的就是那个k数组。
考虑贪心。
我们发现,对于一个正数,当然是希望它的k值越大。
对于一个负数,当然希望它的k值越小。
那么对于每个负数,它的k值最小为1(第一个位置为0)
然后一段正数区间则是递增的。

当然,这样是错误滴。为什么呢?我们有可能把一段正数区间乘2然后合并到前面的负数,这样答案会变大。
这样一直合并合并之后,可能会出现的情况是:k数组会分成一个一个块,每块开头是1(第一块开头为0)然后向后面递增。

所以我们从左到由依次加入数字,然后把当前的数字往前面合并,如果合并到最后当前块为负数就不合并了。
但是数值要去模啊?怎么办?我们发现,负数不会特别小,最少是-2e9,那么只要正数大于4e9的时候就可以往前面疯狂合并即可。
于是我们多记录一个数值表示当前块的数值堆4e9取min即可。

拿到70分的好成绩。

对于100分呢?
我们离线询问,把询问按照有端点排序,然后依次加入数字,做与上面相同的东东。
然后由于询问的左端点不是1,那么就不能直接统计了(废话)
那么这个左端点必定把某一块分割成两个部分。
求出这一块右边部分即可。

那么问题来了:分割后两个部分右边的部分不会被合并吗?
答案是:不会。
因为我们发现,左端点所在的块右边的块的数值是小于0的(否则在做的过程中就已经合并了),我们知道,数值小于0是不能合并的,因此不会合并。

那么利用并查集维护块或是线段树即可。

标程

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cctype>
using namespace std;
const int maxn=500010;
const long long mo=1000000007;struct node{long long le,ri,kk,gg,lazy;
};int n,m,l[maxn],r[maxn],gs,now;
long long a[maxn],b[maxn],c[maxn],mi[maxn],sum[maxn],jl,jr,jk,jg;
long long le[maxn],ri[maxn],k[maxn],zs[maxn],aa[maxn],qsum[maxn],col[maxn],id[maxn],wz[maxn],jll[maxn],qh[maxn],zd[maxn];
node tree[4*maxn];void down_lazy(int x)
{if (tree[x].lazy==1){tree[x*2].le=tree[x].le;tree[x*2+1].le=tree[x].le;tree[x*2].ri=tree[x].ri;tree[x*2+1].ri=tree[x].ri;tree[x*2].kk=tree[x].kk;tree[x*2+1].kk=tree[x].kk;tree[x*2].lazy=tree[x].lazy;tree[x*2+1].lazy=tree[x].lazy;tree[x*2].gg=tree[x].gg;tree[x*2+1].gg=tree[x].gg;tree[x].lazy=0;}
}void change(int x,int l,int r,int st,int en,int le,int ri,int kk,int g)
{if (l==st && r==en){tree[x].le=le;tree[x].ri=ri;tree[x].kk=kk;tree[x].gg=g;tree[x].lazy=1;}else{down_lazy(x);int mid=(l+r)/2;if (mid>=en) change(x*2,l,mid,st,en,le,ri,kk,g);else if (mid<st) change(x*2+1,mid+1,r,st,en,le,ri,kk,g);else{change(x*2,l,mid,st,mid,le,ri,kk,g);change(x*2+1,mid+1,r,mid+1,en,le,ri,kk,g);}}
}void find(int x,int l,int r,int st)
{if (l==r){jl=tree[x].le;jr=tree[x].ri;jk=tree[x].kk;jg=tree[x].gg;}else{down_lazy(x);int mid=(l+r)/2;if (mid>=st) find(x*2,l,mid,st);else find(x*2+1,mid+1,r,st);}
}long long min(long long a,long long b)
{if (a<b) return a;return b;
}void qsort(int ll,int rr)
{int i=ll;int j=rr;long long m=r[(i+j)/2];while (i<=j){while (r[i]<m) i++;while (r[j]>m) j--;if (i<=j){swap(r[i],r[j]);swap(l[i],l[j]);swap(wz[i],wz[j]);i++;j--;}}if (ll<j) qsort(ll,j);if (rr>i) qsort(i,rr);
}long long qsm(long long a,long long b)
{long long t=1;long long y=a;while (b>0){if ((b&1)==1) t=t*y%mo;y=y*y%mo;b/=2;}return t;
}int main()
{//  freopen("data.in","r",stdin);
//  freopen("data.out","w",stdout);freopen("standard.in","r",stdin);freopen("standard.out","w",stdout);mi[0]=1;for (int i=1;i<=500000;i++){mi[i]=mi[i-1]*2%mo;}scanf("%d%d",&n,&m);for (int i=1;i<=n;i++){scanf("%l64d",&a[i]);zd[i]=(zd[i-1]+a[i]*mi[i]%mo)%mo;}for (int i=1;i<=m;i++){scanf("%d%d",&l[i],&r[i]);}for (int i=1;i<=m;i++){wz[i]=i;}qsort(1,m);k[1]=0;le[1]=1;ri[1]=1;zs[1]=a[1];gs=1;aa[1]=a[1];qh[1]=(a[1]+mo)%mo;change(1,1,n,le[gs],ri[gs],le[gs],ri[gs],k[gs],gs);int op=1;while (r[op]==1){jll[wz[op]]=(qh[1]+mo)%mo;op++;}for (int j=2;j<=n;j++){long long zss=a[j]*2;long long aaa=a[j]*2%mo;int kk=1;if (a[j]>0){while (gs>0 && zs[gs]+zss*mi[k[gs]]>0){zss=min(5000000000,zs[gs]+zss*mi[k[gs]]);aaa=(aa[gs]+aaa*mi[k[gs]]%mo+mo)%mo;kk=kk+k[gs];gs--;}if (gs==0){gs++;}else{zss=min(5000000000,zs[gs]+zss*mi[k[gs]]);aaa=(aa[gs]+aaa*mi[k[gs]]%mo+mo)%mo;kk=k[gs]+kk;}ri[gs]=j;k[gs]=kk;zs[gs]=zss;aa[gs]=aaa;qh[gs]=(qh[gs-1]+aaa+mo)%mo;}else{gs++;le[gs]=j;ri[gs]=j;zs[gs]=zss;k[gs]=kk;aa[gs]=aaa;qh[gs]=(qh[gs-1]+aaa+mo)%mo;}change(1,1,n,le[gs],ri[gs],le[gs],ri[gs],k[gs],gs);while (op<=m && j==r[op]){if (l[op]==r[op]){jll[wz[op]]=a[l[op]];op++;}else{jr=0;jl=0;jk=0;jg=0;if (l[op]>1){find(1,1,n,l[op]-1);jll[wz[op]]=(qh[gs]-qh[jg]+mo)%mo;int opt=0;if (jk==jr-jl+1) opt=1;jll[wz[op]]=(jll[wz[op]]+(zd[jr]-zd[l[op]-1]+mo)%mo*qsm(mi[jr-(jk-(l[op]-jl))+opt],mo-2)%mo)%mo;int pd=jl;jr=0;jl=0;jk=0;jg=0;find(1,1,n,l[op]);if (jl!=pd){jll[wz[op]]=(jll[wz[op]]-(zd[jr]-zd[jl-1]+mo)%mo*qsm(mi[jr-jk+1],mo-2)%mo)%mo;}op++;}else{jll[wz[op]]=(qh[gs]+mo)%mo;op++;}}}}for (int i=1;i<=m;i++){printf("%l64d\n",(jll[i]+mo)%mo);}
}

jzoj6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]相关推荐

  1. 6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]

    题目 题目大意 给你一个数列,每次可以选择任意两个相邻的数xxx和yyy,将其删去,并在原来位置插入x+2yx+2yx+2y. 每次询问一个区间,对这个区间进行上述操作.求最后剩下的数最大是多少. 答 ...

  2. 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目 题目大意 有个无限长的数列an{a_n}an​,a1=1a_1=1a1​=1,an=an−1+maxdightk(an−1)a_n=a_{n-1}+maxdight_k(a_{n-1})an​= ...

  3. JZOJ6384【NOIP2019模拟2019.10.23】珂学家

    珂学家 题目描述: 输入: 输出: 输出共mmm行,每行一个非负整数表示答案. 这道题看到是一个区间,便想到了数据结构之类的东西. 但是呢它好像不带修.所以初步判断这是个离线的题目. 再仔细观察发现, ...

  4. jzoj6384. 【NOIP2019模拟2019.10.23】珂学家

    Description Input Output 输出共 行,每行一个非负整数表示答案. Sample Input 2 1 1 2 3 2 1 3 5 Sample Output 4 只能选用试剂1 ...

  5. jzoj6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题解 真的都快忘了. 首先,我们考虑排序,求出一个神奇的排列方式,也就是dfn序. 那么答案必定是在dfn序里面一些连续的段连接起来. 然后我们就判断这玩意儿是否满足在a里面出现过. 于是现在分两步走 ...

  6. 【日常训练】2019-10-24am_xjoi结界[生与死的境界]/codeforces878E_贪心

    题面 现场题面 codeforces878E codeforces878E A sequence of n integers is written on a blackboard. Soon Sash ...

  7. 6360. 【NOIP2019模拟2019.9.18】最大菱形和(rhombus)

    Description Input Output Sample Input 5 5 2 0 1 5 7 3 -4 2 0 -9 8 3 9 0 7 8 2 -4 5 -7 1 4 5 8 7 0 6 ...

  8. JZOJ6362. 【NOIP2019模拟2019.9.18】数星星(star)

    Description Solution 考虑分治,将每一个询问挂在包括它的最大的区间中. 只考虑中点往右的区间的贡献,那么每一个点对于覆盖它的最早的时间有一个贡献. 我们建一个虚树,并且用并查集路径 ...

  9. 野鸡NOI.AC模拟赛【2019.10.26】

    前言 截止至2019.10.2614:222019.10.26\ \ \ \ 14:222019.10.26    14:22 成绩 正题 T1:NOI.AC−T1:NOI.AC-T1:NOI.AC− ...

  10. 2019.10.26日常总结兼一码学成普及模拟4比赛选解

    [题目A]: [题目]: 有 n 只袋鼠(题目假设他们都是母的),你需要给他们组建成家庭. 对于第 i 只袋鼠来说,它的大小用一个数字 Si 来表示. 如果第 i 只袋鼠的大小 Si 达到了第 j 只 ...

最新文章

  1. 那些珍贵的「视觉SLAM」课程资料总结(补充版/完整版)
  2. html滚动条样式自定义,CSS3自定义滚动条样式
  3. 浅析企业开展网站建设具有哪些实际意义?
  4. [Linux实用工具]Ubuntu环境下SSH的安装及使用
  5. 云炬Android开发笔记 15评价晒单功能实现(自定义评分控件和仿微信自动多图选择控件)
  6. spring boot 异常汇总
  7. Markovs Chains采样
  8. 输出以下的杨辉三角形(要求输入个数字,表示需要输出几行)
  9. java 异步调用 shell_Java 实现异步调用
  10. qt, connect参数,Qt::DirectConnection,Qt::QueuedConnection
  11. iOS开发中对NSArray或者NSMutableArray中的内容排序
  12. 你一定要了解的Kubernetes
  13. fatal error LNK _X
  14. get请求500_050 Servlet的请求req与响应resp
  15. 2019计算机保研 中科院信工所夏令营+中科院软件所九推记录
  16. 吴伯凡-认知方法论-效率高并不一定是好事
  17. SQL Server之dbo
  18. 【微信小程序】使出千手浮图—回滚式
  19. 验证座机号码(中国 如:010-XXXXXXXX)
  20. c语言规定对于一个正常运行的c程序,下列叙述中正确的是,计算机二级C语言复习第*周...

热门文章

  1. [HDU 5956] The Elder (斜率DP + 可持久化单调队列)
  2. exactly-once在Flink里的实现
  3. 安卓开发—Android基础
  4. 大陆地区OpenStack项目Core现状(截至2016年1月28日,转载自陈沙克日志)
  5. 数学笔记——导数1(导数的基本概念)
  6. 计算机edp测试是什么测试,五、信息工具--(一)EDP:电子数据处理
  7. response返回中文乱码
  8. mac photoshop cs5.1 序列号
  9. matinee和matin区别_法语小灶 | an和année, jour和journée有什么区别?
  10. VproC#混合编程,Basler相机加载显示实时图像