codechef Chef and Problems
2024-09-30 06:51:55
终于补出这道:一直耽搁到现在
找到一个代码可读性很好的分块temp;
题意:给一个长度为n 的数组 A,Q次询问,区间相等数的最大范围是多少?
数据范围都是10e5;
当然知道分块了;
传统分块看各种累;
找了一份很好的tmp<新技能get;
#include<bits/stdc++.h> using namespace std;
const int N =;
const int S =; int a[N],res[S][N],occ[N];
int ans[N];
//一种很神奇的分块写法
//想办法 在其他题目扩展 struct query
{
int L,R,id;
bool operator <(const query& a)const
{
return R<a.R;
}
}q[N]; int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
int s=sqrt(n);
for (int i=;i<n;i++) scanf("%d",&a[i]); for (int i=;i*s<n;i++)//预处理0-->sqrt(n)个块,每块的宽度这里并不一定相同
{ //这里是从i*s-->n 都计算出区间的最大值
for (int j=;j<=m;j++) occ[j]=-;
int now=;
for (int j=i*s;j<n;j++)
{
if (occ[a[j]]==-) occ[a[j]]=j;
else now=max(now,j-occ[a[j]]);
res[i][j]=now;
}
} for (int i=;i<k;i++)
scanf("%d%d",&q[i].L,&q[i].R),q[i].id=i,q[i].L--,q[i].R--;
sort(q,q+k);//按询问R排序 for (int i=;i<=m;i++)
occ[i]=-; int r=; for (int i=;i<k;i++)
{
while (r<q[i].R)//q[i].L<q[i].R;
{
++r;
occ[a[r]]=r;//预处理出前几个
} int tmp=res[q[i].L/s+][q[i].R];//计算已经可以分块的数据
for (int j=q[i].L;j<(q[i].L/s+)*s&&j<=q[i].R;j++)
tmp=max(tmp,occ[a[j]]-j);//利用询问的单调询问开始不足一块的数据
ans[q[i].id]=tmp;
} for (int i=;i<k;i++) printf("%d\n",ans[i]);
return ;
}
最新文章
- 用NSCalendar和UICollectionView自定义日历,并实现签到显示
- JS中获得当前时间的年月
- js错误
- SqlServer常用语句参考
- C#Form窗体通过代码改变尺寸
- CloudStack4.2 二级镜像存储测试
- C - Catch That Cow
- javascript 关于一周前一个月前的处理方法
- (转)Java 的swing.GroupLayout布局管理器的使用方法和实例
- WDLINUX (Centos5.8) 安装 bcmath
- vue 父组件向子组件传递事件/调用事件
- MySQL技术内幕 InnoDB存储引擎(笔记)
- 微信小程序 canvas导出图片模糊
- js获取浏览器和设备的 width和height,
- valgrind--内存泄漏检测(转)
- 12.14 Daily Scrum
- vue系列之获取多选框中被选中的值
- Python open详解
- Jmeter - json参数处理
- 写了一个兼容IE9的图片放大器(基于vue)