[HNOI2017]影魔
来源:互联网 发布:网络安全法正式实施 编辑:程序博客网 时间:2024/04/28 21:05
题目大意
给定一个长度为
现在给你
题目分析
首先,我们可以考虑把
我们将贡献
这个怎么计算呢?显然我们要正着做一遍反着做一遍来把左右端点的贡献都给求出来,这里只讨论正着做,反着的话你把数组reverse一下,把询问区间翻转一下就一样了。
首先我们用单调栈处理出一个点后面的第一个比它大的数的位置,记为
这样做,我们能把所有
时间复杂度
代码实现
#include <algorithm>#include <iostream>#include <cstdio>#include <cctype>using namespace std;typedef long long LL;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}int buf[30];void write(LL x){ if (x<0) putchar('-'),x=-x; for (;x;x/=10) buf[++buf[0]]=x%10; if (!buf[0]) buf[++buf[0]]=0; for (;buf[0];putchar('0'+buf[buf[0]--]));}const int N=200050;const int Q=200050;struct segment_tree{ LL tag[N<<2],sum[N<<2]; int size[N<<2]; void ADD(int x,LL delta){sum[x]+=1ll*delta*size[x],tag[x]+=delta;} void clear(int x,int l,int r) { if (tag[x]) { if (l!=r) ADD(x<<1,tag[x]),ADD(x<<1|1,tag[x]); tag[x]=0; } } void update(int x){size[x]=size[x<<1]+size[x<<1|1],sum[x]=sum[x<<1]+sum[x<<1|1];} void modify(int x,int st,int en,int l,int r,int delta) { clear(x,l,r); if (st==l&&en==r) { ADD(x,delta),clear(x,l,r); return; } int mid=l+r>>1; if (en<=mid) modify(x<<1,st,en,l,mid,delta); else if (mid+1<=st) modify(x<<1|1,st,en,mid+1,r,delta); else modify(x<<1,st,mid,l,mid,delta),modify(x<<1|1,mid+1,en,mid+1,r,delta); update(x); } LL query(int x,int st,int en,int l,int r) { clear(x,l,r); if (st==l&&en==r) return sum[x]; int mid=l+r>>1; if (en<=mid) return query(x<<1,st,en,l,mid); else if (mid+1<=st) return query(x<<1|1,st,en,mid+1,r); else return query(x<<1,st,mid,l,mid)+query(x<<1|1,mid+1,en,mid+1,r); } void build(int x,int l,int r) { tag[x]=0; if (l==r) { sum[x]=0,size[x]=1; return; } int mid=l+r>>1; build(x<<1,l,mid),build(x<<1|1,mid+1,r),update(x); }}t;LL res[Q];int stack[N],a[N],R[N];int top,n,q,p1,p2;struct qy{ int l,r,id; bool operator<(qy const x)const{return l<x.l;}}ask[Q];void calc(){ t.build(1,1,n+1),sort(ask+1,ask+1+q),a[stack[top=0]=n+1]=n+1; for (int i=n;i>=1;--i) { for (;top&&a[stack[top]]<a[i];--top); R[i]=stack[top],stack[++top]=i; } for (int i=n,cur=q;i>=1;--i) { t.modify(1,i+1,R[i],1,n+1,p2),t.modify(1,R[i],R[i],1,n+1,p1-2*p2); for (;cur&&ask[cur].l==i;--cur) res[ask[cur].id]+=t.query(1,1,ask[cur].r,1,n+1); }}int main(){ freopen("sf.in","r",stdin),freopen("sf.out","w",stdout); n=read(),q=read(),p1=read(),p2=read(); for (int i=1;i<=n;++i) a[i]=read(); for (int i=1;i<=q;++i) ask[i].l=read(),ask[i].r=read(),ask[i].id=i; calc(),reverse(a+1,a+1+n); for (int i=1;i<=q;++i) ask[i].l=n+1-ask[i].l,ask[i].r=n+1-ask[i].r,swap(ask[i].l,ask[i].r); calc(); for (int i=1;i<=q;++i) write(res[i]),putchar('\n'); fclose(stdin),fclose(stdout); return 0;}
0 0
- [HNOI2017]影魔
- HNOI2017 影魔
- BZOJ4826 [Hnoi2017]影魔
- [bzoj4826][HNOI2017]影魔
- bzoj4826 [Hnoi2017]影魔
- bzoj4826 hnoi2017影魔
- BZOJ4826: [Hnoi2017]影魔
- BZOJ4826: [Hnoi2017]影魔
- [HNOI2017]影魔sf
- 4826: [Hnoi2017]影魔
- 【BZOJ4826】【HNOI2017】影魔
- [题解]bzoj4826 HNOI2017 影魔
- [BZOJ4826][HNOI2017]影魔-单调栈-线段树
- [单调栈 扫描线] BZOJ 4826 [Hnoi2017]影魔
- BZOJ4826: [Hnoi2017]影魔(扫描线+树状数组)
- BZOJ4826:[Hnoi2017]影魔 (单调栈+扫描线+线段树)
- HNOI2017滚粗记
- HNOI2017滚粗记
- hibernate教程--二级缓存详解
- 给定一个字符串,请你将字符串重新编码,将连续的字符替换成“连续出现的个数+字符”。比如字符串AAAABCCDAA会被编码成4A1B2C1D2A。
- java IO流遍历文件
- poj1094_Sorting It All Out_拓扑排序
- 【干货合辑】就需要这些独家数据库优化技巧
- [HNOI2017]影魔
- 九位数字按位分别被除
- 第三天C++
- 动态规划―采药
- 深入理解辗转相除法
- NYOJ305 表达式求值(河南省第四届ACM省赛)
- sqoop从mysql迁移数据到hive中遇到的问题
- 客户端存储和应用程序存储
- HWS中SpriteKit教程实际运行错误的调整