POJ 3368 Frequent values(线段树区间合并)
来源:互联网 发布:东德歧视中国人知乎 编辑:程序博客网 时间:2024/06/05 11:22
传送门:http://poj.org/problem?id=3368
题意:输入一个n个元素排好序的序列,然后输入q个查询。每次查询一个区间,输出这个区间内出现最多次数的数字的次数,但是因为序列已经是排序好的,所以相等的数字一定是相邻的。所以用线段树,记录每个区间的最左边的数字,和最右边的数字,左边的连续长度,右边的连续长度,最长的总长度。然后查询的时候区间合并一下就可以搞了。
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <iostream>#include <vector>#include <map>#include <queue>#include <ctime>using namespace std;typedef long long LL;typedef pair<int,int> pii;#define PB push_back#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define calm (l+r)>>1const int INF=1e9+7;const int maxn=100000;int ll[maxn<<2],rr[maxn<<2],llen[maxn<<2],rlen[maxn<<2],sum[maxn<<2];int n,m;inline void pushup(int rt){ sum[rt]=max(sum[rt<<1],sum[rt<<1|1]); ll[rt]=ll[rt<<1]; rr[rt]=rr[rt<<1|1]; llen[rt]=llen[rt<<1]; rlen[rt]=rlen[rt<<1|1]; if(ll[rt<<1]==rr[rt<<1]){ if(rr[rt<<1]==ll[rt<<1|1]){ llen[rt]=llen[rt<<1]+llen[rt<<1|1]; } } if(ll[rt<<1|1]==rr[rt<<1|1]){ if(ll[rt<<1|1]==rr[rt<<1]){ rlen[rt]=rlen[rt<<1|1]+rlen[rt<<1]; } } if(rr[rt<<1]==ll[rt<<1|1]){ sum[rt]=max(sum[rt],rlen[rt<<1]+llen[rt<<1|1]); } sum[rt]=max(sum[rt],max(llen[rt],rlen[rt]));}void build(int l,int r,int rt){ ll[rt]=rr[rt]=llen[rt]=rlen[rt]=sum[rt]=0; if(l==r){ int x;scanf("%d",&x); ll[rt]=rr[rt]=x; llen[rt]=rlen[rt]=sum[rt]=1; return; } int m=calm; build(lson);build(rson); pushup(rt);}struct node{ int ll,rr,llen,rlen,sum; node(){} node(int ll,int rr,int llen,int rlen,int sum):ll(ll),rr(rr),llen(llen),rlen(rlen),sum(sum){}};node merge(node left,node right){ node ans; ans.sum=max(left.sum,right.sum); ans.ll=left.ll; ans.rr=right.rr; ans.llen=left.llen; ans.rlen=right.rlen; if(left.ll==left.rr){ if(left.rr==right.ll){ ans.llen=left.llen+right.llen; } } if(right.ll==right.rr){ if(left.rr==right.ll){ ans.rlen=left.rlen+right.rlen; } } if(left.rr==right.ll){ ans.sum=max(ans.sum,left.rlen+right.llen); } ans.sum=max(ans.sum,max(ans.llen,ans.rlen)); return ans;}node query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return node(ll[rt],rr[rt],llen[rt],rlen[rt],sum[rt]); } int m=calm; if(R<=m)return query(L,R,lson); if(L>m)return query(L,R,rson); return merge(query(L,R,lson),query(L,R,rson));}int main(){ //freopen("input.txt","r",stdin); while(scanf("%d",&n)!=EOF){ if(n==0)break; scanf("%d",&m); build(1,n,1); while(m--){ int L,R;scanf("%d%d",&L,&R); printf("%d\n",query(L,R,1,n,1).sum); } } //printf("[Run in %.1fs]\n",(double)clock()/CLOCKS_PER_SEC); return 0;}
0 0
- POJ 3368 Frequent values(线段树区间合并)
- POJ 3368 Frequent values(线段树区间合并)
- POJ 3368 Frequent values(RMQ/线段树区间合并)
- uva11235 Frequent values(线段树区间合并)
- poj 3368 Frequent values(区间合并)
- poj 3368 Frequent values(离散化+线段树区间求最值)
- UVA - 11235 Frequent values 线段树 区间合并
- hdu-1806:Frequent values(线段树区间合并)
- 区间离散化+线段树区间求最值poj 3368 Frequent values
- poj 3368 Frequent values //线段树
- poj 3368 --Frequent values 线段树
- 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(线段树)
- poj-3368 Frequent values 线段树
- 开源Math.NET基础数学类库使用(02)矩阵向量计算
- 如何解决Sublime Text 3不能正确显示中文的问题
- Android Studio如何导入第三方工程包
- 《AngularJS》--指令的相互调用
- [__NSCFString ma_MD5String]: unrecognized selector sent to instance 0x7ffeb34aaa80'
- POJ 3368 Frequent values(线段树区间合并)
- sql server 2008r2安装注意的问题
- set集合
- C#.net 环境下使用OpenCV
- [个人草稿,请忽略]convention需求
- Jfinal小结
- 我的初学笔记
- 《python简明教程》学习笔记(2)-dict,set,入参等
- 水平导航栏