poj3368--线段树统计区间的最大频率

来源:互联网 发布:淘宝5年老店条件 编辑:程序博客网 时间:2024/06/06 04:02

今天又做了点图论和线段树的题目,比较有感触的就是这道,一开始感觉有点像hotel那道题,感觉记录区间的左右值和左右的最大频率以及总的最大频率即可,最后比较取最大,

后来在初始化的时候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(); } }


原创粉丝点击