题目链接
题目分析
太久不使用 map 以致快忘记还有这个东西了(⊙﹏⊙)。。。vector 的二维存储也是试了几次才想起来→_→
本题的题面与大意与CF 1141F1 Same Sum Blocks(Easy)相同,只是数据范围扩大了,由之前的 n <= 50 变成了 n <= 1500 。此时最多可能产生 1500 * 1500 个不同的区间和的值。如果还用上一题博客中的数组记录出现过的区间和的大小,遍历数组选择当前计算的区间和的存储方式,会超时。若使用 visit 数组将区间和作为数组下标记录区间和为第几次出现,数组长度将达到(1500 * 105 * 2)的 大小,会内存超限。最后想起可以用 map ,最多只会出现 1500 * 1500 个值,不会出现内存超限的情况。记录区间和的两个端点也是用 STL 的 vector 来存储以免内存超限。
剩下的就是贪心了,详情请见CF 1141F1 Same Sum Blocks(Easy)。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node{int l,r;};
map<int,int> mp;
vector<vector<node> > vec;
bool cmp(node a,node b){
return a.r<b.r;
}
int num[1510];
int main()
{
int n,add=15000000;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
int cnt=1;
for(int i=1;i<=n;i++){
int sum=0;
for(int j=i;j<=n;j++){
sum+=num[j];
if(mp[sum]==0){
mp[sum]=cnt;
vector<node> tmp;
vec.push_back(tmp);
node st;
st.l=1;
st.r=0;
vec[cnt-1].push_back(st);
node a;
a.l=i;
a.r=j;
vec[cnt-1].push_back(a);
cnt++;
}
else{
int ind=mp[sum];
vec[ind-1][0].l++;
node a;
a.l=i;
a.r=j;
vec[ind-1].push_back(a);
}
}
}
for(int i=0;i<cnt-1;i++){
//cout<<i<<" "<<vec[i][0].l<<endl;
sort(vec[i].begin()+1,vec[i].end(),cmp);
int tmp=1,last=1;
for(int j=2;j<=vec[i][0].l;j++){
if(vec[i][j].l>vec[i][last].r){
tmp++;
last=j;
}
}
vec[i][0].r=tmp;
}
int maxn=0,inda=0;
for(int i=0;i<cnt-1;i++){
if(vec[i][0].r>maxn){
maxn=vec[i][0].r;
inda=i;
}
}
printf("%d\n",maxn);
int lain=1;
printf("%d %d\n",vec[inda][1].l,vec[inda][1].r);
for(int i=2;i<=vec[inda][0].l;i++){
if(vec[inda][i].l>vec[inda][lain].r){
printf("%d %d\n",vec[inda][i].l,vec[inda][i].r);
lain=i;
}
}
return 0;
}