【bzoj1699/USACO2007】Balanced Lineup排队——RMQ问题
题目链接
很明显的求区间最大最小值问题,可以用st表做,不过ccz 大爷教我用zkw线段树来解决这种问题,感觉很好用><
对于1~n的序列,我们先转化成0~n-1,(方便之后的xor),然后求一个最小的mx=(1<<i)使得mx>=n,这样就保证了是一棵满二叉树,叶子结点为0~mx-1。
然后考虑对于每层建立一个数组tr[mx],拿最顶层来说,我们可以把它根据左右子树划分为0~mx/2-1,mx/2~mx-1,这样的话当i<=mx/2-1时,tr[i]即为i~mx/2-1的最大(小)值,当i>=mx/2,时,tr[i]即为mx/2~mx-1的最大(小)值(也就是左后缀,右前缀)。
往下的每一层的数组都类似如此。
当我们需要查询l~r时,现将l--,r--,然后我们要找到lca(l,r),这样的话最大(小)值就是max/min(tr[l],tr[r])。
当然我们并不需要真的去用倍增求lca,仔细观察可以发现,当最底层为第0层的时候,它们的lca就在 l^r的二进制位数-1 那一层。
不过这样的话查询仍是logn的,我们可以先预处理出0~1023的位数,1024~220 的位数我们可以通过log(a/b)=log(a)-log(b)求出。
具体实现细节看代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 const int N=5e4+10; 5 int a[N],tr[20][N],tr1[20][N]; 6 int wei[1024],ok[1024]; 7 int read(){ 8 int ans=0,f=1;char c=getchar(); 9 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 10 while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();} 11 return ans*f; 12 } 13 int mx=1,h=0; 14 /*-----------------------------------------------------*/ 15 void build(int l,int r,int x,int p){ 16 if(l==r){tr1[x][r]=tr[x][l]=a[l];return;} 17 if(!p){ 18 tr1[x][r]=tr[x][r]=a[r]; 19 for(int i=r-1;i>=l;i--){ 20 tr[x][i]=std::max(a[i],tr[x][i+1]); 21 tr1[x][i]=std::min(a[i],tr1[x][i+1]); 22 } 23 } 24 else{ 25 tr1[x][l]=tr[x][l]=a[l]; 26 for(int i=l+1;i<=r;i++){ 27 tr[x][i]=std::max(a[i],tr[x][i-1]); 28 tr1[x][i]=std::min(a[i],tr1[x][i-1]); 29 } 30 } 31 } 32 int main(){ 33 int n=read(),q=read(),ce=0;wei[0]=0; 34 for(int i=0;i<=9;i++)ok[(1<<i)]=1; 35 for(int i=1;i<=1023;i++)wei[i]=ok[i]?wei[i-1]+1:wei[i-1]; 36 do{mx*=2;}while(mx<n); 37 for(int i=0;i<=n-1;i++){ 38 a[i]=read(); 39 } 40 int ff; 41 for(int i=1;i<=mx>>1;i<<=1){ 42 ff=0; 43 for(int j=0;j<n;j+=i){ 44 build(j,j+i-1,ce,ff); 45 ff^=1; 46 } 47 ce++; 48 } 49 while(q--){ 50 int l=read(),r=read(); 51 l--;r--; 52 int x=l^r,p=0; 53 if(x>=1024)p=wei[x/1024]+10; 54 else p=wei[x]; 55 if(!p)printf("0\n"); 56 else printf("%d\n",std::max(tr[p-1][l],tr[p-1][r])-std::min(tr1[p-1][l],tr1[p-1][r])); 57 } 58 return 0; 59 }
bzoj1699
ccz 大爷的简洁版%%%:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 const int N=5e4+10; 5 int a[N],tr[20][N][2]; 6 int wei[1024],ok[1024]; 7 int read(){ 8 int ans=0,f=1;char c=getchar(); 9 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 10 while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();} 11 return ans*f; 12 } 13 int max(int a,int b){return a>b?a:b;} 14 int min(int a,int b){return a<b?a:b;} 15 int mx=1,h=0; 16 /*-----------------------------------------------------*/ 17 int main(){ 18 int n=read(),q=read(),ce=0;wei[0]=0; 19 for(int i=0;i<=9;i++)ok[(1<<i)]=1; 20 for(int i=1;i<=1023;i++)wei[i]=ok[i]?wei[i-1]+1:wei[i-1]; 21 do mx*=2;while(mx<n); 22 for(int i=0;i<=n-1;i++)a[i]=read(); 23 for(int i=1;i<mx;i<<=1){ 24 int(*f)[2]=tr[ce++]; 25 for(int j=i;j<n;j+=i<<1){ 26 f[j-1][0]=f[j-1][1]=a[j-1]; 27 f[j][0]=f[j][1]=a[j]; 28 for(int p=j+1;p<j+i;++p){ 29 f[p][0]=min(f[p-1][0],a[p]); 30 f[p][1]=max(f[p-1][1],a[p]); 31 } 32 for(int p=j-2;p>=j-i;--p){ 33 f[p][0]=min(f[p+1][0],a[p]); 34 f[p][1]=max(f[p+1][1],a[p]); 35 } 36 } 37 } 38 while(q--){ 39 int l=read(),r=read(); 40 l--;r--; 41 int x=l^r,p=0; 42 p=x>>10?wei[x>>10]+10:wei[x]; 43 if(!p)printf("0\n"); 44 else printf("%d\n",max(tr[p-1][l][1],tr[p-1][r][1])-min(tr[p-1][l][0],tr[p-1][r][0])); 45 } 46 return 0; 47 } 48
ccz版
转载于:https://www.cnblogs.com/JKAI/p/7500742.html
【bzoj1699/USACO2007】Balanced Lineup排队——RMQ问题相关推荐
- bzoj 1636 bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队(RMQ)
1699: [Usaco2007 Jan]Balanced Lineup排队 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1514 Solved: ...
- bzoj1699[Usaco2007 Jan]Balanced Lineup排队
Description 每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置 ...
- bzoj 1699: [Usaco2007 Jan]Balanced Lineup排队【st表||线段树】
要求区间取min和max,可以用st表或线段树维护 st表 #include<iostream> #include<cstdio> using namespace std; c ...
- poj 3264 Balanced Lineup RMQ问题 线段树
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One d ...
- [BZOJ] 1637: [Usaco2007 Mar]Balanced Lineup
1637: [Usaco2007 Mar]Balanced Lineup Time Limit: 5 Sec Memory Limit: 64 MB Submit: 697 Solved: 463 ...
- 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列
1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 510 ...
- bzoj 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列
1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 821 ...
- bzoj 1637: [Usaco2007 Mar]Balanced Lineup
1637: [Usaco2007 Mar]Balanced Lineup Time Limit: 5 Sec Memory Limit: 64 MB Submit: 689 Solved: 456 ...
- POJ 3264 Balanced Lineup(RMQ)
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 24349 Accepted: 11348 ...
- poj Balanced Lineup RMQ
Balanced Lineup Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line ...
最新文章
- 龙芯php,龙芯平台硬解1080和4k视频
- 【GAN优化】详解SNGAN(频谱归一化GAN)
- CSS 属性 - 伪类和伪元素的区别
- maya python 开根号_maya python
- js实现小时钟,js中Date对象的使用?
- 自学python后自己接单-自学python后,可以自己独立做什么事情来挣钱吗?
- Asprise OCR v4.0 64位破解...仅供学习使用
- 决策树的实现及可视化方法总结
- uni-app框架介绍
- 微信小程序把view居中_微信小程序view居中
- 合天网安实验室sql注入实验一 WRITE UP
- Windows 10调整色温显示器
- Google广告分类体系
- 创蓝云智短信接口发送短信函数
- 【BZOJ 3993】【SDOI 2015】星际战争
- 顺序表前m和后n元素交换位置
- 吐血整理!140种Python标准库、第三方库和外部工具都有了
- 【TeXstudio】【2】一般的图片和表格的表现形式
- Android 4.2系统的手机使用LEAP企业Wifi网络 ( by quqi99 )
- 华为EROFS文件系统浅析
热门文章
- QQ帐户的申请与登陆 (25 分)(map映射)
- linux python pymssql,如何在UbuntuLinux上将pymssql安装到Python3.4而不是2.7?
- Spark 学习笔记01
- oracle 批量插入 mysql 区别,Mysql与Oracle中批量插入和更新区别
- 组合分类和回归的神经网络模型
- aiohttp 高并发web服务_面试官要是问你如何解决web高并发,你就这样回答
- fastreport实现动态列_excel中如何实现聚光灯效果?
- python2.7 UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5
- Ubuntu16.04 安装Apache2和php后,无法访问phpinfo.php
- linux输出文件内容ssh,Linux ssh ubuntu终端把运行过程输出到文件?