bzoj 3110 [Zjoi2013]K大数查询
2015-11-28 14:10
405 查看
Description
有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
Input*
第一行N,M接下来M行,每行形如1 a b c或2 a b c
Output
输出每个询问的结果Sample Input
2 5 1 1 2 1 1 1 2 2 2 1 1 2 2 1 1 1 2 1 2 3
Sample Output
1 2 1
HINT
【样例说明】第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1 的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是 1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3 大的数是 1 。
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
2操作中abs(c)<=Maxlongint
Key To Problem
据说是线段树套线段树,然而我不服啊,于是就写的线段树套平衡树,写着写着之后就JJ了,所以还是老老实实的写线段树吧。。第一位记录权值,第二位记录区间,虽然常数写的有点大,但毕竟是20s的bz题,不虚不虚。
对于权值在[l,r]的数,建立一棵普通线段树,求解时可二分答案。
Code
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 50010 #define ls tr[rt].l #define rs tr[rt].r #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; struct node { int l,r,lasy,sum; }; node tr[(N<<2)*100]; int n,m,size; int root[N<<2]; void PushDown(int l,int r,int rt) { if(!tr[rt].lasy||l==r)return ; if(!tr[rt].l)tr[rt].l=++size; if(!tr[rt].r)tr[rt].r=++size; int mid=(l+r)>>1; tr[ls].lasy+=tr[rt].lasy; tr[rs].lasy+=tr[rt].lasy; tr[ls].sum+=tr[rt].lasy*(mid-l+1); tr[rs].sum+=tr[rt].lasy*(r-mid); tr[rt].lasy=0; } void PushUp(int rt) { tr[rt].sum=tr[ls].sum+tr[rs].sum; } void insert(int l,int r,int &rt,int L,int R) { if(!rt)rt=++size; PushDown(l,r,rt); if(l==L&&r==R) { tr[rt].sum+=r-l+1; tr[rt].lasy++; return ; } int mid=(l+r)>>1; if(mid>=R)insert(l,mid,tr[rt].l,L,R); else if(mid<L)insert(mid+1,r,tr[rt].r,L,R); else{ insert(l,mid,tr[rt].l,L,mid); insert(mid+1,r,tr[rt].r,mid+1,R); } PushUp(rt); } void build(int l,int r,int rt,int L,int R,int c) { insert(1,n,root[rt],L,R); if(l==r)return ; int mid=(l+r)>>1; if(mid>=c)build(lson,L,R,c); else build(rson,L,R,c); } int ask(int l,int r,int rt,int L,int R) { if(!rt)return 0; PushDown(l,r,rt); if(l==L&&r==R)return tr[rt].sum; int mid=(l+r)>>1; if(mid>=R)return ask(l,mid,tr[rt].l,L,R); else if(mid<L)return ask(mid+1,r,tr[rt].r,L,R); else return ask(l,mid,tr[rt].l,L,mid)+ask(mid+1,r,tr[rt].r,mid+1,R); } int query(int l,int r,int rt,int L,int R,int c) { if(l==r)return l; int mid=(l+r)>>1; int t=ask(1,n,root[rt<<1|1],L,R); if(t+1<=c){ c-=t; return query(lson,L,R,c); }else return query(rson,L,R,c); } int main() { cin>>n>>m; for(int i=1;i<=m;i++) { int opt,x,y,z; scanf("%d%d%d%d",&opt,&x,&y,&z); switch(opt) { case 1:build(1,n,1,x,y,z);break; case 2:printf("%d\n",query(1,n,1,x,y,z));break; } } return 0; }
相关文章推荐
- BZOJ3275 Number (最小割)
- [bzoj1003] [ZJOI2006]物流运输trans
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort
- [bzoj1503][NOI2004]郁闷的出纳员
- [BZOJ2038][2009国家集训队][莫队][分块]小z的袜子
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- [BZOJ2300][HAOI2011][动态凸包]防线修建
- [BZOJ1045][HAOI2008][贪心]糖果传递
- [BZOJ2539][CTSC2000][KM]丘比特的烦恼
- [BZOJ1004][HNOI2008][Burnside引理][DP]Cards
- [BZOJ1202][HNOI2005][并查集]狡猾的商人
- [BZOJ1179][APIO2009][Tarjan][拓扑排序][递推]Atm
- [BZOJ1095][ZJOI2007][线段树]Hide捉迷藏
- [BZOJ1089][SCOI2003][递推][高精度]严格n元树
- [BZOJ1096][ZJOI2007][DP][斜率优化]仓库建设
- [BZOJ1071][SCOI2007][堆]组队
- [BZOJ1499][NOI2005][DP+优化]瑰丽华尔兹
- [BZOJ1266][AHOI2006][最短路][最小割]上学路线