BZOJ 3110: [Zjoi2013]K大数查询
2015-09-06 09:59
316 查看
3110: [Zjoi2013]K大数查询
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2276 Solved: 1021
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 51 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
Sample Output
12
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
解题:整体二分+树状数组改段求段
#include <bits/stdc++.h> using namespace std; const int maxn = 200010; struct QU { int x,y,k,id,cache; } Q[maxn],A[maxn],B[maxn]; int c[2][maxn],ans[maxn]; void add(int *c,int i,int val) { while(i < maxn) { c[i] += val; i += i&-i; } } int sum(int *c,int i,int ret = 0) { while(i > 0) { ret += c[i]; i -= i&-i; } return ret; } void solve(int lt,int rt,int L,int R) { if(lt > rt) return; if(L == R) { for(int i = lt; i <= rt; ++i) if(Q[i].id > -1) ans[Q[i].id] = L; return; } int mid = (L + R)>>1,a = 0,b = 0; for(int i = lt; i <= rt; ++i) { if(Q[i].id == -1) { if(Q[i].k > mid) { add(c[0],Q[i].x,1); add(c[0],Q[i].y+1,-1); add(c[1],Q[i].x,Q[i].x); add(c[1],Q[i].y+1,-Q[i].y-1); A[a++] = Q[i]; }else B[b++] = Q[i]; } else { int tmp = (Q[i].y+1)*sum(c[0],Q[i].y) - sum(c[1],Q[i].y) - (Q[i].x)*sum(c[0],Q[i].x-1) + sum(c[1],Q[i].x-1); if(tmp + Q[i].cache >= Q[i].k) A[a++] = Q[i]; else { Q[i].cache += tmp; B[b++] = Q[i]; } } } for(int i = lt; i <= rt; ++i) { if(Q[i].id == -1 && Q[i].k > mid) { add(c[0],Q[i].x,-1); add(c[0],Q[i].y+1,1); add(c[1],Q[i].x,-Q[i].x); add(c[1],Q[i].y+1,Q[i].y+1); } } for(int i = 0; i < b; ++i) Q[lt + i] = B[i]; for(int i = 0; i < a; ++i) Q[lt + b + i] = A[i]; solve(lt,lt+b-1,L,mid); solve(lt+b,rt,mid+1,R); } int main() { int n,m,op,ask = 0; scanf("%d%d",&n,&m); for(int i = 0; i < m; ++i) { scanf("%d%d%d%d",&op,&Q[i].x,&Q[i].y,&Q[i].k); if(op == 2) Q[i].id = ask++; else Q[i].id = -1; Q[i].cache = 0; } solve(0,m-1,-n,n); for(int i = 0; i < ask; ++i) printf("%d\n",ans[i]); return 0; }
View Code
相关文章推荐
- tableView的基本使用(改良版)
- 9/6使某个view显示在视图最上面
- hibernate的二级缓存
- 多行文本溢出时用省略号表示溢出内容
- jquery JSON的解析方式
- 状态栏图标和通知
- 张国祥老师在宁波金鸟服饰指导制度优化讨论绩效管理原则
- Edit Distance
- Jquery实现拖动
- Spring MVC -- xxx conflicts with existing xxx
- java中GBK编码格式转成UTF8
- Java学习之自动装箱和自动拆箱源码分析
- 将程序配置存储在注册表
- 全球风浪中A股何去何从?
- C# if,ifelse语句
- oc自学-第一个程序
- 基python实现多线程网页爬虫
- poi导出中文名出现乱码或者不出现的的情况
- unicode编码转换成汉字
- 投影曲线的波峰查找