分块入门9 --- 区间众数

👩‍⚕️👩‍🎓💂‍♀️

//写完入门后,这道一直想补,终于拖到了现在d=====( ̄▽ ̄*)b

分块维护每一块的众数(第i块到第j块的众数),所以中间的块预处理就可以得到,旁边的块我们暴力枚举,但这样前面预处理得到的还需要统计它出现次数。这个我们就可以用到二分来找,找中间块最多的那个数,二分找在[x,y]内出现次数,所以我们就需要一个数组来保存某个数所有的出现位置,边界块的每一个数也可以这样找,然后比较更新。这里因为要经常用到a[i]即读入的某个数,但它的大小不是连续的,为了防t也为了满足题目中次数相同取先出现的条件,我们就可以把它标号为出现次序(id),然后再来一个数组专门根据保存它原来的值,a[i]就专门保存它的id,还要思考如何判断a[i]已经编过次序,我们就用map来,其他是用id来做下标,而map就是用a[i]原本的值。

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

  ②这道题来说好像数据蛮水?所以用scanf就行,和read()时间差不多。

  ③不能像平时一样blo=sqrt(n),会超时,所以自己手动定一个,比如80,150就会t了,应该是两边处理时的原因(也许...)

       ④ 用cin的话,前面加上ios::sync_with_stdio(false);cin.tie(0); 虽然还是会慢一点(500ms上下),但是也不会超。

  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

 

posted @ 2019-07-23 14:21  XXrl  阅读(341)  评论(0编辑  收藏  举报