题面:无
做法:①分块在线做法
注意 数组应该先开小维再开大维
AC毒瘤卡常
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
const int N=50010;
using namespace std;
int a[N],f[40][40],fa[N],b[N],c[40][40][N],st[40],ed[40],ans,tot;
int n,m,t,L,R;
inline void prework()
{
t=(int)pow(n*1.0,1.0/3);
int l=0;
if(t) l=n/t;
for(int i=1;i<=t;++i)st[i]=(i-1)*l+1,ed[i]=i*l;
if(ed[t]<n){st[t+1]=ed[t]+1,ed[++t]=n;}
memcpy(b,a,sizeof(a));
sort(b+1,b+1+n);
for(int i=1;i<=n;++i)if(b[i]!=b[i-1]||i==1)fa[++tot]=b[i];
for(int i=1;i<=n;++i)a[i]=lower_bound(fa+1,fa+1+tot,a[i])-fa;
for(int i=1;i<=t;++i){
for(int j=i;j<=t;++j){
for(int k=st[i];k<=ed[j];++k){
c[i][j][a[k]]++;
}
for(int k=1;k<=tot;++k)
f[i][j]=max(f[i][j],c[i][j][k]);
}
}
}
inline void update(int i){
c[L][R][a[i]]++;
ans=ans>c[L][R][a[i]]?ans:c[L][R][a[i]];
}
inline int solve(int x,int y){
int l,r;
for(int i=1;i<=t;++i)if(ed[i]>=x){l=i;break;}
for(int i=1;i<=t;++i)if(ed[i]>=y){r=i;break;}
if(l+1<=r-1){L=l+1,R=r-1;}else L=R=0;
ans=f[L][R];
if(l!=r){
for(int i=x;i<=ed[l];++i)update(i);
for(int i=st[r];i<=y;++i)update(i);
for(int i=x;i<=ed[l];++i)--c[L][R][a[i]];
for(int i=st[r];i<=y;++i)--c[L][R][a[i]];
}else{
for(int i=x;i<=y;++i)update(i);
for(int i=x;i<=y;++i)--c[L][R][a[i]];
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
prework();
int l,r,k;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&l,&r,&k);
int res=solve(l,r);
if(res>=k)printf(">_<\n");
else printf("QAQ\n");
}
return 0;
}
做法②莫队
思路同分块,但离线处理。
而且跑得比分块快。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 50005
int col[N],ask[N][3],n,q,t[N],p[N],anss[N],k,ans;
inline bool cmp(int x,int y){
return ask[x][0]/k<ask[y][0]/k||(ask[x][0]/k==ask[y][0]/k)&&ask[x][1]<ask[y][1];
}
inline void modify(int c,int op){
if(op==-1&&ans==t[c]&&p[t[c]]==1){
ans--;
}
if(op==1&&ans==t[c])ans++;
p[t[c]]--;
t[c]+=op;
p[t[c]]++;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>q;
k=sqrt(n);
for(int i=1;i<=n;i++){
cin>>col[i];
}
int ord[n];
for(int i=1;i<=q;i++){
cin>>ask[i][0]>>ask[i][1]>>ask[i][2];
ord[i]=i;
}
sort(ord+1,ord+1+q,cmp);
for(int l=1,r=0,i=1;i<=q;i++){
int u=ask[ord[i]][0],v=ask[ord[i]][1];
for(;l<u;l++)modify(col[l],-1);
for(;l>u;l--)modify(col[l-1],1);
for(;r>v;r--)modify(col[r],-1);
for(;r<v;r++)modify(col[r+1],1);
anss[ord[i]]=ans;
}
for(int i=1;i<=q;i++){
if(anss[i]>=ask[i][2])cout<<">_<"<<endl;
else cout<<"QAQ"<<endl;
}
return 0;
}
做法③优秀暴力+预处理+分类讨论
其他做法实时更新。