POJ 3368 Frequent values RMQ ST算法/线段树
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 15229 | Accepted: 5550 |
Description
You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.
Input
The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the
query.
The last test case is followed by a line containing a single 0.
Output
For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.
Sample Input
10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0
Sample Output
1 4 3
Source
题意:
给你一个非递减序列。有m次询问,每次询问区间之间出现最多的数字出现的次数。
题解:
RMQ/线段树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<map> using namespace std ; typedef long long ll; #define inf 100000 inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //****************************************************************** struct ss{ int l,r,num,v; }a[100001]; int counts[100001]; int dp[100001][63],n,m,p; void rmq_init() { memset(dp,0,sizeof(dp)); for(int i=1;i<=p;i++){ dp[i][0]=counts[i]; } int k=floor(log((double)n+1)/log(2.0)); for(int j=1;j<=k;j++) { for(int i=1;i+(1<<j)-1<=p;i++) { int oo=i+(1<<(j-1)); dp[i][j]=max(dp[i][j-1],dp[oo][j-1]); } } } int RMQ(int x,int y) { int oo=floor(log((double)y-x+1)/log(2.0)); return max(dp[x][oo],dp[y-(1<<(oo))+1][oo]); } void work() { int l,r; for(int i=1;i<=m;i++) { scanf("%d%d",&l,&r); if(a[l].num==a[r].num){ cout<<r-l+1<<endl; } else { int ans=a[l].r-l+1; ans=max(r-a[r].l+1,ans); l=a[l].num+1; r=a[r].num-1; if(l<=r) ans=max(ans,RMQ(l,r)); cout<<ans<<endl; } } } void init() { int f=0,r=0,l=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i].v); if(f&&a[i].v!=a[i-1].v) { counts[p]=r-l+1; for(int j=l;j<=r;j++) a[j].num=p,a[j].l=l,a[j].r=r; r++; p++; l=r; } else if(f){ r++; } if(f==0) { l=1; r=1,f=1; p=1; } } counts[p]=r-l+1; for(int j=l;j<=r;j++) a[j].num=p,a[j].l=l,a[j].r=r; // for(int i=1;i<=n;i++)cout<<counts[i]<<" "; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(n==0)break; init(); rmq_init(); work(); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<map> using namespace std ; typedef long long ll; #define inf 100000 inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //****************************************************************** struct ss { int l,r,v,num; }tr[100001*7],a[500001]; int counts[200001]; int n,m,p; void build(int k,int s,int t) { tr[k].l=s; tr[k].r=t; if(s==t){ tr[k].v=counts[s]; return ; } int mid=(s+t)>>1; build(k<<1,s,mid); build(k<<1|1,mid+1,t); tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v); } int ask(int k,int s,int t) { if(s==tr[k].l&&t==tr[k].r) { return tr[k].v; } int mid=(tr[k].l+tr[k].r)>>1; if(t<=mid)return ask(k<<1,s,t); else if(s>mid)return ask(k<<1|1,s,t); else { return max(ask(k<<1,s,mid),ask(k<<1|1,mid+1,t)); } } void init() { int f=0,l=0,r=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i].v); if(f&&a[i].v!=a[i-1].v) { counts[p]=r-l+1; for(int j=l;j<=r;j++)a[j].l=l,a[j].r=r,a[j].num=p; r++; l=r; p++; } else if(f){ r++; } if(!f) { f=l=1; r=p=1; } } counts[p]=r-l+1; for(int j=l;j<=r;j++)a[j].l=l,a[j].r=r,a[j].num=p; ///for(int i=1;i<=p;i++)cout<<counts[i]<<" "; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { p=0; if(n==0)break; init(); build(1,1,p); // cout<<p<<endl; int x,y; for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); if(a[x].num==a[y].num){ cout<<y-x+1<<endl; } else { int ans=a[x].r-x+1; ans=max(ans,y-a[y].l+1); x=a[x].num+1; y=a[y].num-1; if(x<=y)ans=max(ask(1,x,y),ans); cout<<ans<<endl; } } } return 0; }