前缀和 差分

2021-01-26  本文已影响0人  Tsukinousag

1.前缀和

原题链接

这里的数据不需要两个数组,开两个就ME了,从左往右,从上往下直接滚动s数组就行

#include<iostream>
#include<cstring>

using namespace std;

const int N=5050;

int s[N][N];

int main()
{
    int N,R;
    cin>>N>>R;
    int n=R,m=R;
    for(int i=0;i<N;i++)
    {
        int x,y,w;
        cin>>x>>y>>w;
        x++,y++;
        s[x][y]+=w;
        n=max(n,x),m=max(m,y);//至少是R*R初坐标开始枚举
    }
    //求二维前缀和
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+s[i][j];
    //求边长为R的正方形的最大值
    int res=0;
    for(int i=R;i<=n;i++)
        for(int j=R;j<=m;j++)
            res=max(res,s[i][j]-s[i-R][j]-s[i][j-R]+s[i-R][j-R]);
    cout<<res<<endl;
    return 0;
}

2.差分

原题链接

#include<iostream>
#include<algorithm>

using namespace std;

typedef long long LL;
const int N=1e5+10;

int a[N];

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
        
    //先处理成差分数组
    for(int i=n;i>1;i--)
        a[i]-=a[i-1];
    
    LL p=0,q=0;    
    //b2~bn中找正数总和与负数总和
    for(int i=2;i<=n;i++)
    {
        if(a[i]>0)  p+=a[i];
        else if(a[i]<0) q-=a[i];
    }
    cout<<max(p,q)<<endl;
    cout<<abs(p-q)+1<<endl;
    
    return 0;
}

3.差分与前缀和

原题链接

#include<iostream>
#include<map>

using namespace std;
const int N=1e4+10;

map<pair<int,int> ,bool> existed;
int d[N],c[N];

int main()
{
    int n,p,h,m;
    cin>>n>>p>>h>>m;
    for(int i=1;i<=m;i++)
    {
        int a,b;
        cin>>a>>b;
        if(a>b)swap(a,b);
        if(existed[make_pair(a,b)])continue;
        d[a+1]--,d[b]++;
        existed[make_pair(a,b)]=true;
    }
    for(int i=1;i<=n;i++)
    {
        c[i]=c[i-1]+d[i];
        cout<<c[i]+h<<endl;
    }
}
上一篇下一篇

猜你喜欢

热点阅读