poj 3368

来源:互联网 发布:淘宝订单信息编辑 编辑:程序博客网 时间:2024/06/06 12:52

求一段非递减序列出现频率最高的数字的个数,线段树做的,每个节点记录5个信息

lv:区间最左边的数字,rv:区间最右边的数字

ml:与区间最左边的数字相等的数字的个数,mr:与区间最右边的数字相等的数字的个数

maxv:区间中出现频率最高的数字的个数,然后通过线段树查询即可

以后看到与区间信息有关的题目要想到用线段树

 1 #include <iostream> 2     #include <cstdio> 3     using namespace std; 4     const int maxn=100000+10; 5     struct node 6     { 7         int ml,mr,maxv,lv,rv; 8     }; 9     node sgtree[maxn*3];10     int a[maxn];11     int n,q,tot,k;12     int ql,qr;13     void Init(int no,int l,int r)14     {15         if(l==r)16         {17             sgtree[no].maxv=1;18             sgtree[no].ml=1;19             sgtree[no].mr=1;20             sgtree[no].lv=a[tot];21             sgtree[no].rv=a[tot++];22             return;23         }24         int mid=l+(r-l)/2;25         int tl=no*2+1,tr=no*2+2;26         Init(tl,l,mid);27         Init(tr,mid+1,r);28         sgtree[no].maxv=max(sgtree[tl].maxv,sgtree[tr].maxv);29         if(sgtree[tl].rv==sgtree[tr].lv)30             sgtree[no].maxv=max(sgtree[no].maxv,sgtree[tl].mr+sgtree[tr].ml);31         sgtree[no].lv=sgtree[tl].lv;32         sgtree[no].rv=sgtree[tr].rv;33        sgtree[no].ml=sgtree[tl].ml;34         sgtree[no].mr=sgtree[tr].mr;35         if(sgtree[tl].lv==sgtree[tr].lv) sgtree[no].ml+=sgtree[tr].ml;36         if(sgtree[tr].rv==sgtree[tl].rv) sgtree[no].mr+=sgtree[tl].mr;37     }38     int Query(int no,int l,int r)39     {40         int tl=no*2+1,tr=no*2+2;41         if(l>=ql&&r<=qr) return sgtree[no].maxv;42         int mid=l+(r-l)/2;43         if(ql>mid) return Query(no*2+2,mid+1,r);44         else if(qr<=mid) return Query(no*2+1,l,mid);45         else46         {47             int t1=Query(tl,l,mid);48             int t2=Query(tr,mid+1,r);49             int ans=max(t1,t2);50             if(sgtree[tl].rv==sgtree[tr].lv)51             {52             int a1=(mid-ql+1)>=sgtree[tl].mr?sgtree[tl].mr:(mid-ql+1);53             int a2=(qr-mid)>=sgtree[tr].ml?sgtree[tr].ml:(qr-mid);54             ans=max(ans,a1+a2);55             }56             return ans;57         }58     }59     int main()60     {61         while(scanf("%d",&n)&&n)62         {63             scanf("%d",&k);64             int i;65             for(i=0;i<n;i++) scanf("%d",&a[i]);66             tot=0;67             Init(0,1,n);68             int l,r;69             int ans;70             for(i=0;i<k;i++)71             {72                 scanf("%d%d",&ql,&qr);73                ans=Query(0,1,n);74                printf("%d\n",ans);75             }76         }77         return 0;78     }

 

原创粉丝点击