jzoj4438 K小数查询
Data Constraint
n<=80000,所有数字的绝对值不超过5000000
Solution
这是一道分块的板题 但是并不是那么好写的
一般来说我们都按照根号n为块的大小进行分块
那么,对于某一个询问或者查找
就对于整块的部分打个标记
而对于边缘部分暴力处理
这道题目的时限给了8s
我们分块之后处理k小数就用二分来解决
这样的复杂度比较玄学
code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int N=80005,sz=300; //sz为块大小
struct edge{int s,w,d;
} a[N];
int x,y,z,l,r,n,m,i,mid,j,t;
int s[sz],rr[sz],add[sz];
int read(){int sum=0,p=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') p=-1;c=getchar();}while (c>='0'&&c<='9') {sum=sum*10+c-'0';c=getchar();}return sum*p;
}
inline bool cmp(edge a,edge b){ return a.d<b.d;}
inline int search(int h,int k){int l,r,mid;l=s[h],r=rr[h];while (l<r-1){mid=(l+r)>>1;if (a[mid].d+add[h]<k) l=mid; else r=mid;}while (a[r].d+add[h]>=k&&r>=l) r--;return r-s[h]+1;
}
inline int get(int x,int y,int k){int l,r,i,ans;ans=0;l=(x+sz-1)/sz,r=(y+sz-1)/sz;if (l==r){fo(i,x,y) if (add[l]+a[a[i].s].d<k) ans++;return ans;}fo(i,l+1,r-1) ans+=search(i,k);fo(i,x,rr[l]) if (a[a[i].s].d+add[l]<k) ans++;fo(i,s[r],y) if (a[a[i].s].d+add[r]<k) ans++;return ans;
}
int main(){freopen("1.in","r",stdin);freopen("1.out","w",stdout);n=read();fo(i,1,n) a[i].d=read(),a[i].w=i;fo(i,1,(n+sz-1)/sz){s[i]=(i-1)*sz+1,rr[i]=min(i*sz,n);sort(a+s[i],a+rr[i]+1,cmp);}fo(i,1,n) a[a[i].w].s=i;//a[i].s为a[i].w的一个反函数//因为我们的数组经过了排序,所以更改x就等于更改a[a[x].s]m=read();while (m){m--;t=read(),x=read(),y=read(),z=read();if (t==1){l=(x+sz-1)/sz,r=(y+sz-1)/sz;if (l==r){fo(i,x,y) a[a[i].s].d+=z;sort(a+s[l],a+rr[l]+1,cmp); //注意这里的排序范围,整一个块都要重新排序,而不是x到yfo(i,s[l],rr[l]) a[a[i].w].s=i;} else {fo(i,l+1,r-1) add[i]+=z;fo(i,x,rr[l]) a[a[i].s].d+=z;fo(i,s[r],y) a[a[i].s].d+=z;sort(a+s[l],a+rr[l]+1,cmp),sort(a+s[r],a+rr[r]+1,cmp);fo(i,s[l],rr[l]) a[a[i].w].s=i;fo(i,s[r],rr[r]) a[a[i].w].s=i;}} else {l=-5000000,r=5000000; //二分while (l<r-1){mid=(l+r)>>1;if (get(x,y,mid)<z) l=mid; else r=mid;}if (get(x,y,l)<=z) r=l;printf("%d\n",r);}}
}
jzoj4438 K小数查询相关推荐
- 牛客练习赛87 B k小数查询(STL)
题目链接 由于序列是n的一个排列,那么问题就十分简单啦.先找到x所在的位置然后左右扩展做乘法原理就行了. unordered_map<int, int> L; unordered_map& ...
- szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】
树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...
- python【蓝桥杯vip练习题库】ALGO-1区间k大数查询
试题 算法训练 区间k大数查询 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示 ...
- 洛谷 P3332 [ZJOI2013]K大数查询 解题报告
P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...
- BZOJ3110: [Zjoi2013]K大数查询
BZOJ3110: [Zjoi2013]K大数查询 Description 有N个位置,M个操作. 操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如 ...
- 蓝桥杯-区间k大数查询(java)
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB问题描述给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个.输入格式第一行包含一个数n,表示序列长度.第二行包含n个 ...
- nyoj 1261 音痴又音痴的LT(离散化+树状数组求K小数)
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=1261 解题思路:比较水的题,用离散化+树状数组求K小数即可,先用一次离线处理. #inc ...
- JZOJ 100043. 【NOIP2017提高A组模拟7.13】第K小数
Description 有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少. Input 输入文件包含三行. 第一行为 ...
- java:区间k大数查询
试题 算法训练 区间k大数查询 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示 ...
最新文章
- 《我想进大厂》之mysql夺命连环13问
- go标准库的学习-crypto/sha1
- java web 多语言_基于 Selenium WebDriver 实现多语言环境下自动化截图
- micropython教程modbus_基于S7-300400 CPU集成PN接口的Modbus TCP在TIA Portal的使用入门教程...
- [Delphi]怎样访问Internet Explorer中的WebBrowser
- Doris之Rollup的注意事项和常见问题
- Node.js 推荐20多个学习网站及书籍
- vue+node全栈移动商城【8】-vant新建注册页面
- 关于 Matlab R2014a下载与安装流程
- 3t硬盘 xp_解决方案:如何在Windows XP SP3 32位系统下识别3T容​​量GPT格式的硬盘...
- ds18b20触摸没反应_写个DS18B20初始化程序,死活没反应
- python内置函数( )可以返回列表长度_python内置函数总结
- 电梯服务器系统,OTS电梯服务器TT使用说明.pdf
- 【Win10】【亲手解决】华硕笔记本重装系统遇到的各种问题【包括重启会自动修复】
- VLAN tag格式
- New Online Judge P1128-绝地求生(多源bfs)
- 数据分析学习技能树 | 养成数据分析师的品质和思维模式
- C++ Primer 第5版--练习9.14
- 计算当前时间距离元年一月一日的总天数,并显示现在是星期几
- 中标linux+银河麒麟=中标麒麟