[XJOI]栈
来源:互联网 发布:淘宝强光手电 编辑:程序博客网 时间:2024/05/16 13:39
题目大意
有
有
题目分析
考虑离线,把所有操作挂在对应端点上,然后从左向右扫描线。
以时间为下标建立线段树,考虑动态地维护当前扫到的单调栈在每一时间点的答案。
这个就十分套路了,和WC2013的楼房重建差不多。
先考虑如何查询,定义函数
如果
设
如果
否则,右边的单调栈会直接被
如果我们一直这样递归下去,复杂度是没有保证的,怎么办呢?
令
假如我们的
那么这个
我们研究里面的嵌套函数调用了多少次。
首先,在我的区间还不是一个完整的线段树区间时,
其次,我们的查询操作会下放到
至于
于是总的时间复杂度就是
代码实现
#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 Q=200050;const int M=Q<<1;const int S=Q<<2;struct query{ int opt,x,ti,val; query (int opt_=0,int x_=0,int ti_=0,int val_=0){opt=opt_,x=x_,ti=ti_,val=val_;} bool operator<(query const qry)const{return x<qry.x||x==qry.x&&opt<qry.opt;}}qy[M];inline int max(int x,int y){return x>y?x:y;}struct segment_tree{ int mx[S]; LL f[S]; int querymax(int x,int st,int en,int l,int r) { if (st==l&&en==r) return mx[x]; int mid=l+r>>1; if (en<=mid) return querymax(x<<1,st,en,l,mid); else if (mid+1<=st) return querymax(x<<1|1,st,en,mid+1,r); else return max(querymax(x<<1,st,mid,l,mid),querymax(x<<1|1,mid+1,en,mid+1,r)); } LL querysum(int x,int st,int en,int l,int r,int p) { if (l==r) return (mx[x]>p)*mx[x]+p; int mid=l+r>>1;bool cvr=st==l&&en==r; if (en<=mid) return querysum(x<<1,st,en,l,mid,p); else if (mid+1<=st) return querysum(x<<1|1,st,en,mid+1,r,p); else { int rmx=cvr?mx[x<<1|1]:querymax(x<<1|1,mid+1,en,mid+1,r); if (rmx>p) return (cvr?f[x]:querysum(x<<1,st,mid,l,mid,rmx))+querysum(x<<1|1,mid+1,en,mid+1,r,p)-rmx; else return querysum(x<<1,st,mid,l,mid,p); } } void update(int x,int l,int r) { mx[x]=max(mx[x<<1],mx[x<<1|1]); int mid=l+r>>1; f[x]=querysum(x<<1,l,mid,l,mid,mx[x<<1|1]); } void modify(int x,int y,int l,int r,int val) { if (l==r) { mx[x]=val; return; } int mid=l+r>>1; if (y<=mid) modify(x<<1,y,l,mid,val); else modify(x<<1|1,y,mid+1,r,val); update(x,l,r); }}t;int n,q,cnt,qid;LL ans[Q];void calc(){ sort(qy+1,qy+1+cnt); for (int cur=1,ptr;cur<=cnt;) { for (ptr=cur;cur<=cnt&&qy[cur].x==qy[ptr].x&&!qy[cur].opt;++cur) t.modify(1,qy[cur].ti,1,q,qy[cur].val); for (;cur<=cnt&&qy[cur].x==qy[ptr].x&&qy[cur].opt==1;++cur) ans[qy[cur].val]=t.querysum(1,1,qy[cur].ti,1,q,0); for (;cur<=cnt&&qy[cur].x==qy[ptr].x;++cur) t.modify(1,qy[cur].ti,1,q,0); }}int main(){ freopen("stack.in","r",stdin),freopen("stack.out","w",stdout); n=read(),q=read(); for (int i=1;i<=q;++i) { int opt=read(); if (opt==1) { int l=read(),r=read(),x=read(); qy[++cnt]=query(0,l,i,x),qy[++cnt]=query(2,r,i,0); } else { int x=read(); qy[++cnt]=query(1,x,i,++qid); } } calc(); for (int i=1;i<=qid;++i) write(ans[i]),putchar('\n'); fclose(stdin),fclose(stdout); return 0; }
- [XJOI]栈
- XJOI 公交线路
- XJOI泡泡糖
- XJOI 迷你火车头
- XJOI 1003 质因数分解
- [XJOI]黑白树
- 【XJOI】path 题解
- [XJOI]排序列表
- xjoi奋斗群群赛2
- xjoi奋斗群群赛3
- xjoi奋斗群群赛4
- xjoi奋斗群群赛5
- XJOI划水总结
- xjoi奋斗群群赛6
- xjoi奋斗群群赛7
- XJOI Week1 奋斗总结
- xjoi奋斗群群赛8
- XJOI 38 感想
- dijkstra的优先队列优化
- Java Swing实现高仿电脑版微信
- hibernate里面的一对多关系映射
- Qt5基础(三)Qt登录对话框学习笔记
- 21article元素
- [XJOI]栈
- Linux虚拟机不能上网问题解决
- Shell脚本学习-语法篇(下)
- uint8_t / uint16_t / uint32_t /uint64_t 是什么数据类型
- MyISAM和InnoDB的区别
- 关键字final的用法与特点
- Open-falcon 邮件模块mail-provider
- 背景差分法 Background Subtraction Methods
- 22section元素