分塊入門9 --- 區間衆數

👩‍⚕️👩‍🎓💂‍♀️ios

//寫完入門後,這道一直想補,終於拖到了如今d=====( ̄▽ ̄*)bc++

分塊維護每一塊的衆數(第i塊到第j塊的衆數),因此中間的塊預處理就能夠獲得,旁邊的塊咱們暴力枚舉,但這樣前面預處理獲得的還須要統計它出現次數。這個咱們就能夠用到二分來找,找中間塊最多的那個數,二分找在[x,y]內出現次數,因此咱們就須要一個數組來保存某個數全部的出現位置,邊界塊的每個數也能夠這樣找,而後比較更新。這裏由於要常常用到a[i]即讀入的某個數,但它的大小不是連續的,爲了防t也爲了知足題目中次數相同取先出現的條件,咱們就能夠把它標號爲出現次序(id),而後再來一個數組專門根據保存它原來的值,a[i]就專門保存它的id,還要思考如何判斷a[i]已經編過次序,咱們就用map來,其餘是用id來作下標,而map就是用a[i]本來的值。數組

tips: ①用lld(一把辛酸淚┭┮﹏┭┮)ide

  ②這道題來講好像數據蠻水?因此用scanf就行,和read()時間差很少。ui

  ③不能像平時同樣blo=sqrt(n),會超時,因此本身手動定一個,好比80,150就會t了,應該是兩邊處理時的緣由(也許...)spa

       ④ 用cin的話,前面加上ios::sync_with_stdio(false);cin.tie(0); 雖然仍是會慢一點(500ms上下),可是也不會超。code

  1 #include<bits/stdc++.h>
  2 #include<iostream>
  3 #include<stack>
  4 #include<algorithm>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<cstring>
  8 #define mem(a) memset(a,0,sizeof(a))
  9 #define mem1(a) memset(a,-1,sizeof(a))
 10 #define fio ios::sync_with_stdio(false);cin.tie(0)
 11 #define ll long long
 12 //#define mp make_pair
 13 #define inf 0x3f3f3f3f
 14 const int N=1e5+5;
 15 const int M=1e4+10;
 16 const int mod=9973;
 17 using namespace std;
 18 int blo,num,belong[N],n,cnt[N],r[N],l[N];
 19 ll a[N],k,pmx[M][M],d[N],id;
 20 vector<int>ve[N];
 21 map<int,int>mp;
 22 inline ll read()
 23 {
 24     ll sum=0,f=1;
 25     char c=getchar();
 26     while(c>'9'||c<'0') {if(c=='-') f=-f; c=getchar();}
 27     while(c>='0'&&c<='9') sum=sum*10+c-'0', c=getchar();
 28     return sum*f;
 29 }
 30 inline void prework(int now)
 31 {
 32     mem(cnt);
 33     int mx=0,ans=0;
 34     for(int i=l[now];i<=n;i++)
 35     {
 36         cnt[a[i]]++;
 37         if(cnt[a[i]]>mx || (cnt[a[i]]==mx && d[a[i]]<d[ans]))
 38         {
 39             mx=cnt[a[i]];
 40             ans=a[i];
 41         }
 42         pmx[now][belong[i]]=ans;
 43     }
 44 }
 45 inline void build()
 46 {
 47     blo=80; //
 48     num=(n%blo)? n/blo+1:n/blo;
 49     for(int i=1;i<=n;i++)
 50     {
 51         belong[i]=(i-1)/blo+1;
 52     }
 53     for(int i=1;i<=num;i++)
 54     {
 55         l[i]=(i-1)*blo+1;
 56         r[i]=i*blo;
 57     }
 58     r[num]=n;
 59     for(int i=1;i<=num;i++)
 60         prework(i);
 61 }
 62 inline ll binarys(int now,int x,int y)
 63 {
 64     return upper_bound(ve[now].begin(),ve[now].end(),y)-lower_bound(ve[now].begin(),ve[now].end(),x);
 65 }
 66 inline ll query(int x,int y)
 67 {
 68     ll ans=pmx[belong[x]+1][belong[y]-1],mx=binarys(ans,x,y);
 69     for(int i=x;i<=min(y,r[belong[x]]);i++)
 70     {
 71          ll t=binarys(a[i],x,y);
 72          if(t>mx || (t==mx && d[a[i]]<d[ans]))
 73          {
 74              ans=a[i];
 75              mx=t;
 76          }
 77     }
 78     if(belong[x]!=belong[y])
 79     {
 80         for(int i=l[belong[y]];i<=y;i++)
 81         {
 82              ll t=binarys(a[i],x,y);
 83              if(t>mx || (t==mx && d[a[i]]<d[ans]))
 84              {
 85                 ans=a[i];
 86                 mx=t;
 87              }
 88         }
 89     }
 90     return ans;
 91 }
 92 int main()
 93 {
 94     scanf("%d",&n);
 95     //n=read();
 96     for(int i=1;i<=n;i++)
 97     {
 98         scanf("%lld",&a[i]);
 99          //a[i]=read();
100         if(!mp[a[i]])
101         {
102             mp[a[i]]=++id;
103             d[id]=a[i];
104         }
105         a[i]=mp[a[i]];
106         ve[a[i]].push_back(i);
107     }
108     build();
109     int x,y;
110     for(int i=1;i<=n;i++)
111     {
112          scanf("%d%d",&x,&y);
113          //x=read(),y=read();
114          printf("%lld\n",d[query(x,y)]);
115     }
116     return 0;
117 }
o(* ̄▽ ̄*)o
相關文章
相關標籤/搜索