uva11235 FrequentValues (ST表)

既然他是非降的,那我们可以把这个序列每一位转化成到这位位置连续相同的个数,比如001111233444变成121234112123,然后一个区间内的最大值就是众数的位数。但有个问题,就是这个区间的左端点可能切开了某个连续相同的段,比如1111查后两个,查到的最大值就是4,只要给每一位记一下从他开始的第一个和他不同的数的位置,就能避免切开连续的一段。但还有询问11[1111]11这种情况,就是左右端点都被同一段覆盖,不要写出锅...

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=1e5+10;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 int N,Q;
16 int a[maxn],b[maxn],nxt[maxn],st[maxn][20];
17 
18 inline void getst(){
19     for(int i=N;i;i--){
20         st[i][0]=b[i];
21         for(int j=0;i+(2<<j)-1<=N;j++){
22             st[i][j+1]=max(st[i][j],st[i+(1<<j)][j]);
23         }
24     }
25 }
26 inline int rmq(int l,int r){
27     if(l>r) return 0;
28     int x=log2(r-l+1);
29     return max(st[l][x],st[r-(1<<x)+1][x]);
30 }
31 
32 int main(){
33     //freopen(".in","r",stdin);
34     int i,j,k;
35     while(1){
36         N=rd();if(!N) break;
37         Q=rd();
38         for(i=1;i<=N;i++) a[i]=rd();
39         for(i=1;i<=N;i++) b[i]=(a[i]==a[i-1]?b[i-1]+1:1);
40         for(i=N,j=N+1;i;i--){
41             nxt[i]=j;
42             if(b[i]==1) j=i;
43         }
44         getst();
45         for(i=1;i<=Q;i++){
46             int l=rd(),r=rd();
47             printf("%d\n",max(rmq(nxt[l],r),min(r+1,nxt[l])-l));
48         }
49     }
50     
51     return 0;
52 }

猜你喜欢

转载自www.cnblogs.com/Ressed/p/9748480.html
今日推荐