poj3368--线段树统计区间的最大频率
2012-08-08 19:53
162 查看
今天又做了点图论和线段树的题目,比较有感触的就是这道,一开始感觉有点像hotel那道题,感觉记录区间的左右值和左右的最大频率以及总的最大频率即可,最后比较取最大,
后来在初始化的时候RE了一次,然后就AC了,感觉线段树终于入门了
后来在初始化的时候RE了一次,然后就AC了,感觉线段树终于入门了
import java.io.*; public class Main { static StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); final static int nextInt() throws IOException { in.nextToken(); return (int) in.nval; } class Node { int left,right; int lenum,rignum;//信息域,存储该区间的左右端的元素是什么 int num,lnum,rnum;//存储左端的长度和右端长度以及最长的 Node(int left,int right) { this.left=left; this.right=right; } int mid() { return (right+left)>>1; } int lenght() { return (right-left+1); } } static int number; static int MAX=100010; static Node tree[]=new Node[MAX<<2]; static int data[]=new int[MAX]; void build(int left,int right,int idx) throws IOException { // System.out.println(idx+"&^&^&"); tree[idx]=new Node(left,right); tree[idx].left=left; tree[idx].right=right; if(tree[idx].left==tree[idx].right) { tree[idx].lenum=tree[idx].rignum=data[left]; // System.out.println(data[left]); tree[idx].lnum=tree[idx].rnum=tree[idx].num=1; return; } int mid=tree[idx].mid(); build(left,mid,idx<<1); build(mid+1,right,idx<<1|1); tree[idx].num=tree[idx<<1].num; if(tree[idx<<1|1].num>tree[idx].num) tree[idx].num=tree[idx<<1|1].num; if(tree[idx<<1].rnum+tree[idx<<1|1].lnum>tree[idx].num&&tree[idx<<1].rignum==tree[idx<<1|1].lenum) { tree[idx].num=tree[idx<<1].rnum+tree[idx<<1|1].lnum; } tree[idx].lenum=tree[idx<<1].lenum; tree[idx].rignum=tree[idx<<1|1].rignum; tree[idx].lnum=tree[idx<<1].lnum; tree[idx].rnum=tree[idx<<1|1].rnum; if(tree[idx<<1].lnum==tree[idx<<1].lenght()&&tree[idx<<1].rignum==tree[idx<<1|1].lenum) tree[idx].lnum=tree[idx<<1].lnum+tree[idx<<1|1].lnum; if(tree[idx<<1|1].rnum==tree[idx<<1|1].lenght()&&tree[idx<<1|1].lenum==tree[idx<<1].rignum) tree[idx].rnum=tree[idx<<1|1].rnum+tree[idx<<1].rnum; } int query(int a,int b,int idx) { // System.out.println("idx"+idx); if(tree[idx].left==a&&tree[idx].right==b) { return tree[idx].num; } int mid=tree[idx].mid(); // System.out.println("MID"+mid); int ans1=-1,ans2=-1,ans3=-1,ans=-1; if(mid>=b) { return query(a,b,idx<<1); }else if(mid<a) { return query(a,b,idx<<1|1); } else { int temp1=query(a,mid,idx<<1); int temp2=query(mid+1,b,idx<<1|1); ans3=Math.max(temp1,temp2); int temp=-1; if(tree[idx<<1].rignum==tree[idx<<1|1].lenum) { if(mid-tree[idx<<1].rnum+1>=a) { a=mid-tree[idx<<1].rnum+1; } if(mid+tree[idx<<1|1].lnum<=b) b=mid+tree[idx<<1|1].lnum; temp=b-a+1; } ans3=Math.max(ans3, temp); return ans3; } } void run() throws IOException { while((number=nextInt())!=0) { int qnum=nextInt(); for(int i=1;i<=number;i++) data[i]=nextInt(); build(1,number,1); for(int i=1;i<=qnum;i++) { int a=nextInt(); int b=nextInt(); int ans=query(a,b,1); System.out.println(ans); } } } public static void main(String[] args) throws IOException { new Main().run(); } }
相关文章推荐
- 1012: [JSOI2008]最大数maxnumber 线段树区间统计
- ZOJ 2301 / HDU 1199 Color the Ball 离散化+线段树区间连续最大和
- hdu 1754 I Hate It (线段树--求区间最大值)(基础)
- Codeforces Gym 100733J Summer Wars 线段树,区间更新,区间求最大值,离散化,区间求并
- 大区间统计素数(最大1e11)
- Balanced Lineup POJ - 3264(线段树寻找区间最大值最小值)
- HDU5443 线段树 + 裸 + 求任意区间最大值
- CodeForces - 150C :Smart Cheater (线段树,求最大连续区间)
- 线段树求区间最大值RMQ(单点更新)
- hdu-1754 I Hate It【线段树求区间最大值】
- hdu 1754 I Hate it(线段树的单节点更新,求区间最大值)
- 线段树维护区间最大值hdu1754
- POJ 3264 Balanced Lineup 线段树求区间最大最小(普通线段树,ZKW线段树)
- 9-4(线段树最大值定位,区间合并)
- HDOJ 1754 I Hate It(线段树—求区间最大值与单点更新)
- NYOJ 1185 最大最小值(线段树—区间求最值)
- hdu 1754 线段树区间最大值 单点更新
- POJ 3264 Balanced Lineup(线段树—求区间最大值与最小值差)
- 【ZZULIOJ 2171 】 举世伐唐 【线段树 区间修改+区间最大值】
- hdu 1754 I Hate It (线段树--求区间最大值)(基础)