分块.莫队

分块

1.在线求区间众数问题

# include <bits/stdc++.h>
using namespace std;

const int MAXN=4e4+100;
int a[MAXN],pos[MAXN],val[MAXN],cnt[MAXN],mn[1000][1000];
int t;
map<int,int> mp;
vector<int> G[MAXN];
int check(int l,int r,int x)
{
   return upper_bound(G[x].begin(),G[x].end(),r)-lower_bound(G[x].begin(),G[x].end(),l);
}
int main()
{
   int n,m; scanf("%d%d",&n,&m);
   t=100;
   int tot=0;
   for(int i=1;i<=n;i++){
       scanf("%d",&a[i]);
       pos[i]=(i-1)/t+1;
       if(!mp[a[i]]) mp[a[i]]=++tot,val[tot]=a[i];
       a[i]=mp[a[i]];
       G[a[i]].push_back(i);
  }
   for(int i=1;i<=pos[n];i++){
       memset(cnt,0,sizeof(cnt));
       int l=(i-1)*t+1;
       int maxx=0,id=0;
       for(int j=l;j<=n;j++){
           cnt[a[j]]++;
           if(maxx<cnt[a[j]]||(maxx==cnt[a[j]]&&val[a[j]]<id)) maxx=cnt[a[j]],id=val[a[j]];
           mn[i][pos[j]]=id;
      }
  }
   int x=0;
   while(m--){
       int l,r; scanf("%d%d",&l,&r);
       l=(l+x-1)%n+1,r=(r+x-1)%n+1;
       if(l>r) swap(l,r);
       int ans=0,anss=0;
       if(pos[l]==pos[r]){
           for(int i=l;i<=r;i++){
               int now=check(l,r,a[i]);
               if(ans<now||(now==ans&&val[a[i]]<anss)){
                   ans=now,anss=val[a[i]];
              }
          }
           printf("%d\n",anss);
      }else{
           anss=mn[pos[l]+1][pos[r]-1],ans=check(l,r,mp[anss]);
           for(int i=l;i<=pos[l]*t;i++){
               int now=check(l,r,a[i]);
               if(ans<now||(now==ans&&val[a[i]]<anss)){
                   ans=now,anss=val[a[i]];
              }
          }
           for(int i=(pos[r]-1)*t+1;i<=r;i++){
               int now=check(l,r,a[i]);
               if(ans<now||(now==ans&&val[a[i]]<anss)){
                   ans=now,anss=val[a[i]];
              }
          }
           printf("%d\n",anss);
      }
       x=anss;
  }
   return 0;
}

2.莫队

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN=5e4+100;
int c[MAXN],pos[MAXN],num[MAXN];
int t;
struct Node{
   int l,r,id;
}node[MAXN];
int cmpl(Node a,Node b) { return a.l<b.l; }
int cmpr(Node a,Node b) { return a.r<b.r; }
LL gcd(LL a,LL b) { return b==0?a:gcd(b,a%b); }
LL zz[MAXN],mm[MAXN];
int main()
{
   int n,m; scanf("%d%d",&n,&m);
   t=sqrt(m);
   for(int i=1;i<=n;i++) scanf("%d",&c[i]);
   for(int i=1;i<=m;i++){
       pos[i]=(i-1)/t+1;
       scanf("%d%d",&node[i].l,&node[i].r);
       node[i].id=i;
       zz[i]=0,mm[i]=1;
  }

   sort(node+1,node+m+1,cmpl);
   for(int i=1;i<=pos[m];i++){
       memset(num,0,sizeof(num));
       int l=(i-1)*t+1,r=min(i*t,n);/**/
       sort(node+l,node+r+1,cmpr);
       LL ans=0,fz=0,fm=0,gd=0;
       int low=MAXN,hig=0;
       for(int j=node[l].l;j<=node[l].r;j++){
           low=min(low,c[j]),hig=max(hig,c[j]);
           num[c[j]]++;
      }
       for(int j=low;j<=hig;j++) ans+=1ll*(num[j]-1)*num[j]/2;
       fz=ans,fm=1ll*(node[l].r-node[l].l+1)*(node[l].r-node[l].l)/2;
       if(fz&&fm){
           gd=gcd(fz,fm); fz=fz/gd,fm=fm/gd;
           zz[node[l].id]=fz,mm[node[l].id]=fm;
      }
       for(int j=l+1;j<=r;j++){
           for(int k=node[j-1].l;k<node[j].l;k++){
               num[c[k]]--;
               ans=ans-1ll*num[c[k]];
          }
           for(int k=node[j].l;k<node[j-1].l;k++){
               ans=ans+1ll*num[c[k]];
               num[c[k]]++;
          }
           for(int k=node[j-1].r+1;k<=node[j].r;k++){
               ans=ans+1ll*num[c[k]];
               num[c[k]]++;
          }
           fz=ans,fm=1ll*(node[j].r-node[j].l+1)*(node[j].r-node[j].l)/2;
           if(fz&&fm){
               gd=gcd(fz,fm); fz=fz/gd,fm=fm/gd;
               zz[node[j].id]=fz,mm[node[j].id]=fm;
          }
      }
  }
   for(int i=1;i<=m;i++) printf("%lld/%lld\n",zz[i],mm[i]);
   return 0;
}
/*
6 4
1 2 3 3 3 2
2 6
1 3
3 5
1 6
*/



posted @   fengzlj  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示