[JZOJ4438] K小数查询(经典分块)
来源:互联网 发布:org.apache.tools jar 编辑:程序博客网 时间:2024/05/01 15:40
Description
给你
1 L R x 将L 到R 加上x 2 L R k 求L 到R 第k 小的数
Solution
分块大法好!
我们将序列分成
修改整块的就直接打标记,两边的暴力重构该块
关键在查询!
我们可以二分一个答案(思考一下,二分出来的答案会不会序列中不存在呢?)
然后转化成判定性问题,判断二分出来的答案是不是在第
只需要对于每个块,找该块中小于这个值的个数,全部加起来看是不是
证明一下这样为什么不会出现不存在的答案
假设正确答案是
小于等于
所以二分出来的一定是
Code
#include<cstdio>#include<cstdlib>#include<algorithm>#include<iostream>#include<cstring>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)#define mo 1000000007using namespace std;int pl[500],wz[80605],n,m,size;struct note{ int x,y;}a[80605],b[80605];bool cmp(note x,note y){ return x.x<y.x; }int nt(int k){ return ((k-1)/size+1)*size+1;}int pd(int l,int r,int k){ int p=nt(l),sum=0,i; note k1; k1.x=k; while (nt(p)<r+1) { k1.x-=pl[wz[p]]; sum+=lower_bound(b+p,b+nt(p),k1,cmp)-b-p; k1.x+=pl[wz[p]]; p=nt(p); } if (nt(l)>r) { fo(i,l,r) if (a[i].x<k-pl[wz[i]]) sum++; } else { fo(i,l,nt(l)-1) if (a[i].x<k-pl[wz[i]]) sum++; fo(i,p,r) if (a[i].x<k-pl[wz[i]]) sum++; } return sum;}int main(){ int i,j; cin>>n; size=(int)sqrt(n); fo(i,1,n) { scanf("%d",&a[i].x); b[i].x=a[i].x; b[i].y=i; } j=1; wz[j]=1; while (j+size<=n+1) { sort(b+j,b+j+size,cmp); j+=size; wz[j]=wz[j-size]+1; } if(j!=n+1) sort(b+j,b+n+1,cmp); fo(i,1,n) { if (wz[i]==0) wz[i]=wz[i-1]; a[b[i].y].y=i; } cin>>m; int i1=0; fo(i,1,m) { int p,l,r,k,j; scanf("%d%d%d%d",&p,&l,&r,&k); if (p==1) { j=nt(l); while (nt(j)<=r) { pl[wz[j]]+=k; j=nt(j); } int q; if (nt(l)>r) { fo(q,l,r) a[q].x=b[a[q].y].x=a[q].x+k; sort(b+nt(l)-size,b+nt(l),cmp); fo(q,nt(l)-size,nt(l)-1) a[b[q].y].y=q; } else { fo(q,l,nt(l)-1) a[q].x=b[a[q].y].x=a[q].x+k; sort(b+nt(l)-size,b+nt(l),cmp); fo(q,nt(l)-size,nt(l)-1) a[b[q].y].y=q; fo(q,j,r) a[q].x=b[a[q].y].x=a[q].x+k; sort(b+j,b+nt(j),cmp); fo(q,j,nt(j)-1) a[b[q].y].y=q; } } else { int x=-5000000,y=5000000,mid; while (x<y-1) { mid=(x+y)/2; if (pd(l,r,mid)<=k-1) x=mid; else y=mid; } if (pd(l,r,y)==k-1) printf("%d\n",y); else printf("%d\n",x); } }}
0 0
- [JZOJ4438] K小数查询(经典分块)
- [JZOJ4438]K小数查询
- K小数查询:分块
- K小数查询 分块模板
- 动态区间第K小数 分块/树套树
- K小数查询
- 2017年11月1日提高组 第k小数(二分+分块)
- 【HNOI模拟】 K小数查询
- K小数查询主席树
- 【HNOI2016模拟4.10】 K小数查询
- 【HNOI2016模拟4.10】 K小数查询
- 第K(大)小数
- 第K小数(二分)
- 第K小数(二分)
- poj 2761 线段树(多次查询不覆盖区间的第k小数)
- K小数
- 整体二分入门——区间k小数查询
- 【清华集训2017模拟11.29】K小数查询
- STK Class
- 编写一个PHP函数。求任意n个正负整数里面最大的连续和,要求算法时间复杂度尽可能低。
- 关于RAM与ROM的区别与理解
- Hibernate各种主键生成策略与配置详解
- SIM(Subscriber Identity Module)
- [JZOJ4438] K小数查询(经典分块)
- Java数据处理与流程控制
- 一个C语言程序到执行完文件的全过程(笔记)
- 我心中最好玩的音乐游戏——音符传说
- OPN/SPN/PLMN的区别
- java.lang.NoClassDefFoundError: com/fasterxml/jackson/annotation/JsonView
- 五十音图平假名随机生成
- 剑指Offer-面试题27:二叉搜索树与双向链表
- hdu:1247 Hat’s Words