poj 3368

求一段非递减序列出现频率最高的数字的个数,线段树做的,每个节点记录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         else
46         {
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     }
原文地址:https://www.cnblogs.com/lj030/p/3083694.html