codechef Chef and Problems
终于补出这道:一直耽搁到现在
找到一个代码可读性很好的分块temp;
题意:给一个长度为n 的数组 A,Q次询问,区间相等数的最大范围是多少?
数据范围都是10e5;
当然知道分块了;
传统分块看各种累;
找了一份很好的tmp<新技能get;
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 const int N =100005; 5 const int S =405; 6 7 int a[N],res[S][N],occ[N]; 8 int ans[N]; 9 //一种很神奇的分块写法 10 //想办法 在其他题目扩展 11 12 struct query 13 { 14 int L,R,id; 15 bool operator <(const query& a)const 16 { 17 return R<a.R; 18 } 19 }q[N]; 20 21 int main() 22 { 23 int n,m,k; 24 scanf("%d%d%d",&n,&m,&k); 25 int s=sqrt(n); 26 for (int i=0;i<n;i++) scanf("%d",&a[i]); 27 28 for (int i=0;i*s<n;i++)//预处理0-->sqrt(n)个块,每块的宽度这里并不一定相同 29 { //这里是从i*s-->n 都计算出区间的最大值 30 for (int j=1;j<=m;j++) occ[j]=-1; 31 int now=0; 32 for (int j=i*s;j<n;j++) 33 { 34 if (occ[a[j]]==-1) occ[a[j]]=j; 35 else now=max(now,j-occ[a[j]]); 36 res[i][j]=now; 37 } 38 } 39 40 for (int i=0;i<k;i++) 41 scanf("%d%d",&q[i].L,&q[i].R),q[i].id=i,q[i].L--,q[i].R--; 42 sort(q,q+k);//按询问R排序 43 44 45 for (int i=1;i<=m;i++) 46 occ[i]=-1; 47 48 int r=0; 49 50 for (int i=0;i<k;i++) 51 { 52 while (r<q[i].R)//q[i].L<q[i].R; 53 { 54 ++r; 55 occ[a[r]]=r;//预处理出前几个 56 } 57 58 int tmp=res[q[i].L/s+1][q[i].R];//计算已经可以分块的数据 59 for (int j=q[i].L;j<(q[i].L/s+1)*s&&j<=q[i].R;j++) 60 tmp=max(tmp,occ[a[j]]-j);//利用询问的单调询问开始不足一块的数据 61 ans[q[i].id]=tmp; 62 } 63 64 for (int i=0;i<k;i++) printf("%d\n",ans[i]); 65 return 0; 66 }
随性Code