CF 1141F2 Same Sum Blocks (Hard)

CF 1141F2 Same Sum Blocks(Hard)

题目链接

我是题目链接戳我呀>_<

题目分析

太久不使用 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;
}

猜你喜欢

转载自blog.csdn.net/qq_36711868/article/details/89606699