poj 3368_Frequent values_线段树
来源:互联网 发布:北京市人口分布数据 编辑:程序博客网 时间:2024/06/11 22:41
题目大意
给定一个不下降的序列,给定几个区间,求区间中连续的最多的数
思路
开一个线段树,记录
1.max 表示当前区间连续的最大值
2.x 表示该区间表示序列的第几位
3.lt,rt表示区间的左右分别为那个数
4,l,r为区间的左右连续的个数
然后就显而易见可以很容易的建一颗树,详见代码(我都不想复述了)
做的时候有一个地方写错了一点点,一直该不出来
建树的时候可以将右区间设为(m+1,r)来让线段树的每一个节点表示点而不是一个线段
#include <stdio.h>#include <cstring>#include <string>using namespace std;#define fill(x,y) memset(x,y,sizeof(x))int a[100010];struct tree{ int max,l,r,x,lt,rt;}t[1000005];int k=0,ans=0,xx,yy;int max(int x,int y){ return x>y?x:y;}int min(int x,int y){ return x<y?x:y;}int create(int p,int l,int r){ int m=(l+r)/2; t[p].max=t[p].l=t[p].r=t[p].x=t[p].lt=t[p].rt=0; if (r==l) { k++; t[p].x=k; return 0; } create(p*2,l,m); create(p*2+1,m+1,r);}int make(int p,int l,int r){ int m=(l+r)/2; if (t[p].x!=0) { t[p].l=t[p].r=t[p].max=1; t[p].lt=t[p].rt=a[t[p].x]; return 0; } make(p*2,l,m); t[p].l=t[p*2].l; t[p].lt=t[p*2].lt; make(p*2+1,m+1,r); t[p].r=t[p*2+1].r; t[p].rt=t[p*2+1].rt; if (t[p].lt==t[p].rt) { t[p].max=r-l+1; t[p].l=r-l+1; t[p].r=r-l+1; } t[p].max=max(t[p*2].max,t[p*2+1].max); if (t[p*2].rt==t[p*2+1].lt) { if (t[p*2].lt==t[p*2+1].lt) { t[p].l=t[p*2].l+t[p*2+1].l; t[p].max=max(t[p].max,t[p].l); } else if (t[p*2].rt==t[p*2+1].rt) { t[p].r=t[p*2].r+t[p*2+1].l; t[p].max=max(t[p].max,t[p].r); } } if (t[p*2].r+t[p*2+1].l>t[p].max&&t[p*2].rt==t[p*2+1].lt) t[p].max=t[p*2].r+t[p*2+1].l;}int count(int p,int l,int r,int x,int y){ if (x<=l&&y>=r) return t[p].max; int m=(l+r)/2; if (y<=m) return count(p*2,l,m,x,y); if (x>m) return count(p*2+1,m+1,r,x,y); int mx=1,mx1,mx2; if (t[p*2].rt==t[p*2+1].lt) { mx=min(m-x+1,t[p*2].r); mx+=min(y-m,t[p*2+1].l); } mx1=count(p*2,l,m,x,m); mx2=count(p*2+1,m+1,r,m+1,y); mx=max(mx1,mx); mx=max(mx2,mx); return mx;}int main(){ int n,m; while (~scanf("%d",&n)&&n) { scanf("%d",&m); k=0; for (int i=1;i<=n;i++) scanf("%d",&a[i]); memset(&t,0,sizeof(t)); create(1,1,n); make(1,1,n); for (int i=1;i<=m;i++) { scanf("%d%d",&xx,&yy); printf("%d\n",count(1,1,n,xx,yy)); } }}
1 1
- poj 3368_Frequent values_线段树
- POJ_3368_Frequent values_线段树
- POJ3368_Frequent values_线段树
- POJ_3368_Frequent values_线段树/ST稀疏表
- pku 3368_Frequent values
- POJ 3368 线段树
- poj 3368 又一线段树
- poj 3368 (线段树pascal)
- poj 3368 线段树(转换)
- poj 3368 Frequent values //线段树
- poj 3368 --Frequent values 线段树
- poj 3368 离散化+线段树
- POJ 3368 Frequent values RMQ / 线段树
- poj 3368 Frequent values(线段树)
- POJ 3368 Frequent values 线段树
- poj 3368 Frequent values#线段树
- POJ 3368 Frequent values 线段树
- POJ 3368 Frequent values(线段树)
- Python爬虫:获取链家,搜房,大众点评的数据
- 机器学习基础---概率论基础知识
- 今天我开通博客了
- Eclipse中使用Maven构建多模块项目
- HttpURLConnection_get 网络请求
- poj 3368_Frequent values_线段树
- wifi破解
- js 移动端 tab切换栏下使用多个Swiper
- OPENGL—环境配置
- Algorithm-Gossip(1) 河内之塔 / 汉罗塔
- 动态规划之求最短路径(java版)
- Solr简介(1)
- 计算机视觉之统计形状模型——Stasm源码阅读
- 树莓派+超声波模块