The basic principle of program encoding is to use a symbolic value or string length instead of a continuous symbol with the same value (continuous symbols constitute a continuous "Trip ". So that the length of the symbol is less than the length of the original data. Only when the Code of each row or column changes, record the code and the number of duplicates of the same Code at a time to compress the data.
Run Length Encoding (RLE)
Example: 5555557777733322221111111
Travel Code: (5, 6) (7, 5) (3, 3) (2, 4) (1, 7)
A good solution:
Use value [I] Count [I] to represent the value and number of occurrences of segment I, respectively;
Num [p] left [p] Right [p] indicates the number of the segment where position P is located and the position of the left and right endpoints respectively.
The result of each query (left, right) is the maximum value of the following three parts: number of elements from left to left, number of elements from right to right, num [left] + 1 to num [right]- the maximum value of count in Segment 1.
Special case: if left and right are in the same segment, the answer is R-L + 1.
The solution is as follows:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 100001;int n,q;int d[maxn][35];int a[maxn];int value[maxn],count_[maxn];int num[maxn],left[maxn],right[maxn];void RMQ_int(){ for(int i=0;i<n;i++) d[i][0]=count_[i]; for(int j=1; (1<<j)<=n; j++) for(int i=0; i+(1<<j)-1<n; i++) d[i][j]=max(d[i][j-1],d[i+(1<<j-1)][j-1]);}int RMQ(int L,int R){ int k=0; while((1<<(k+1))<=(R-L+1)) k++; return max(d[L][k],d[R-(1<<k)+1][k]);}int main(){ while(scanf("%d",&n)!=EOF){ if(n==0) break; scanf("%d",&q); memset(count_,0,sizeof(count_)); memset(num,0,sizeof(num)); memset(left,0,sizeof(left)); memset(right,0,sizeof(right)); memset(d,0,sizeof(d)); for(int i=0;i<n;i++) scanf("%d",&a[i]); int temp = a[0]; int t=0; value[t]=temp;count_[t]++; num[0]=t;left[0]=0; for(int i=1;i<n;i++){ if(a[i]==temp){ count_[t]++; num[i]=t;left[i]=left[i-1]; } else{ for(int j=left[i-1];j<i;j++){ right[j]=i-1; } temp = a[i]; t++; value[t] = temp;count_[t]++; num[i]=t;left[i]=i; } } t++; for(int i=left[n-1];i<n;i++){ right[i]=n-1; } RMQ_int(); int left_,right_; int ans=0; for(int i=0;i<q;i++){ scanf("%d%d",&left_,&right_); left_--;right_--; if(num[left_]==num[right_]) ans=right_-left_+1; else{ ans=max(right[left_]-left_+1,right_-left[right_]+1); if(num[left_]+1 > num[right_]-1) ans=max(ans,0); else{ ans=max(ans,RMQ(num[left_]+1,num[right_]-1)); } } printf("%d\n",ans); } } return 0;}
Ultraviolet A 11235 frequent values (travel code + interval minimum value query)