Loj 6285. 数列分块入门 9

题目描述

给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及询问区间的最小众数。

输入格式

第一行输入一个数字 nnn。

第二行输入 nnn 个数字,第 i 个数字为 aia_iai,以空格隔开。

接下来输入 nnn 行询问,每行输入两个数字 lll、rrr,以空格隔开。

表示查询位于 [l,r][l,r][l,r] 的数字的众数。

输出格式

对于每次询问,输出一行一个数字表示答案。

样例

样例输入

4
1 2 2 4
1 2
1 4
2 4
3 4

样例输出

1
2
2
2

数据范围与提示

对于 100% 100\%100% 的数据,1≤n≤100000,−231≤others 1 \leq n \leq 100000, -2^{31} \leq \mathrm{others}1n100000,231others、ans≤231−1 \mathrm{ans} \leq 2^{31}-1ans2311。

  1 #include<bits/stdc++.h>
  2 using namespace std; 
  3 #define F(i,a,b) for(int i=a;i<=b;i++) 
  4 #define D(i,a,b) for(int i=a;i>=b;i--) 
  5 #define ms(i,a)  memset(a,i,sizeof(a)) 
  6 #define st(x)   ( (x-1)*B+1) 
  7 #define ed(x)   ( min(n, x*B))    
  8 #define bl(x)   ( (x-1)/B+1) 
  9 #define sum(x)  ( (n-1)/B+1)  
 10 
 11 int inline read(){
 12     int x=0 ;char c=getchar(); 
 13     while (c<'0' || c>'9') c=getchar(); 
 14     while (c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar(); 
 15     return x; 
 16 }
 17 
 18 int const maxn=100003; 
 19 
 20 int n,m,B,cnt[maxn][401],v[401][401],num[401][401]; 
 21 int a[maxn],b[maxn],c[maxn],tmp[maxn];  
 22 
 23 int query(int l,int r){
 24     int x=bl(l); 
 25     int y=bl(r); 
 26     int V,NUM=0;  
 27     if(x+1<=y-1){
 28         V=v[x+1][y-1]; 
 29         NUM=num[x+1][y-1];  
 30     }
 31     int s,e; 
 32     tmp[0]=0;  
 33     if(x==y){
 34         F(i,l,r) {
 35             tmp[++tmp[0]]=a[i]; 
 36             c[a[i]]++; 
 37         }
 38     }else {
 39         s=l;e=ed(x);  
 40         F(i,s,e) {
 41             tmp[++tmp[0]]=a[i];  
 42             c[a[i]]++;  
 43         }
 44         s=st(y);e=r;  
 45         F(i,s,e){
 46             tmp[++tmp[0]]=a[i]; 
 47             c[a[i]]++;  
 48         }
 49     }
 50     F(i,1,tmp[0]) {
 51         int t=x+1<=y-1?  cnt[tmp[i]][y-1]-cnt[tmp[i]][x]: 0;  
 52         if(c[tmp[i]]+t>NUM || ( c[tmp[i]]+t ==NUM  && V> tmp[i])) {
 53             V=tmp[i]; NUM=c[tmp[i]]+t;  
 54         }
 55     }
 56     F(i,1,tmp[0])  c[tmp[i]]=0;  
 57     return V;  
 58 }
 59 
 60 int main(){
 61     n=read(); 
 62     //m=read();
 63     m=n;  
 64     F(i,1,n) a[i]=b[i]=read(); 
 65     sort(b+1,b+n+1); 
 66     int k=unique(b+1,b+n+1)-b-1; 
 67     F(i,1,n) a[i]=lower_bound(b+1,b+k+1,a[i])-b; 
 68     B=(int)sqrt(n); 
 69     int t=sum(n);  
 70     F(i,1,t) {
 71         ms(0,c);  
 72         int s=st(i); 
 73         int e=ed(i); 
 74         F(j,s,e) c[a[j]]++;
 75         F(j,1,k) cnt[j][i]=cnt[j][i-1]+c[j];  
 76     }
 77     F(i,1,t){
 78         ms(0,c);   
 79         F(j,i,t){
 80             int V=v[i][j-1]; 
 81             int NUM=num[i][j-1];  
 82             int s=st(j); 
 83             int e=ed(j);  
 84             F(p,s,e){
 85                 c[a[p]]++ ; 
 86                 if (c[a[p]]> NUM || (NUM==c[a[p]] && a[p] < V)) {
 87                     V=a[p]; NUM=c[a[p]];  
 88                 }
 89             }
 90             v[i][j]=V; 
 91             num[i][j]=NUM;
 92         }
 93     }
 94     int x=0; 
 95     ms(0,c);  
 96     while (m--){
 97         int l=read(); 
 98         int r=read(); 
 99         x=1; 
100         //l=(l+x-1+n) % n+1;  
101         //r=(r+x-1+n) % n+1;
102         if(l>r) swap(l,r); 
103         printf("%d\n",x=b[query(l,r)]);
104     }
105     return 0;  
106 }
View Code

 

posted @ 2018-09-25 22:24  zjxxcn  阅读(248)  评论(0编辑  收藏  举报