前缀和/差分

cWing795
不想写题解

#include<iostream>
#define M 100006
using namespace std;
int s[M],l,r,n,m;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;++i)
    {
        int d;
        cin>>d;
        s[i]=s[i-1]+d;
    }
    for(int i=1;i<=m;++i)
    {
        cin>>l>>r;
        cout<<(s[r]-s[l-1])<<'\n';
    }
}

CodeForces - 1352E
谁还不会直接上天吧

#include<bits/stdc++.h>
using namespace std;
int max(int a,int b)
{
	if(a>b)return a;
	return b;
}
int main(){
	int n;
	cin>>n;
	while(n--){
		int a[8006]={0},s[8006]={0},sum[8006]={0},mx=0,cnt=0;
		int m;
		cin>>m;
		for(int i=1;i<=m;++i)
		{
			int a;
			cin>>a;
			s[a]++;
			mx=max(mx,a);
			sum[i]=sum[i-1]+a;
		}
		int l=2;
		while(l<m)
		{
			for(int i=l;i<=m;++i)
			{
				int b=sum[i]-sum[i-l];
				if(b<=mx)a[b]=1;
			}
			l++;
		}
		for(int i=2;i<=mx;++i){
			if(a[i])cnt+=s[i];
		}
		cout<<cnt<<endl;
	}
}

HDU - 1003

#include<stdio.h>
#define M 100000001
int ch[100006]={0};
int main()
{
    int n,m,date;
    scanf("%d",&n);
    for(int j=1;j<=n;++j)
    {
        int l=1,top=-M,sum=0,a,b;
        scanf("%d",&m);
        for(int i=1;i<=m;++i)
        {
            scanf("%d",&date);
            sum=sum+date;
            if(sum>top){top=sum;a=l;b=i;}
            if(sum<0){sum=0;l=i+1;}
        }
        printf("Case %d:\n",j);
        printf("%d %d %d\n",top,a,b);
        if(j!=n) printf("\n");
    }
 }

AcWing797差分模板题

#include<iostream>
#define M 100006
using namespace std;
int s[M],b[M],l,r,c,n,m,last;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;++i)
    {
    	int d;
        cin>>d;
        s[i]=d-last;
        last=d;
    }
    for(int i=1;i<=m;++i)
    {
        cin>>l>>r>>c;
        b[l]+=c;
        b[r+1]-=c;
    }
    cout<<s[1]+b[1];
    s[1]+=b[1];
    for(int i=2;i<=n;++i)
    {
    	s[i]+=s[i-1]+b[i];
    	cout<<' '<<s[i];
	}
}

CodeForces - 1000C

#include<iostream>
#include<algorithm>
#define ll long long int
using namespace std;
int n,t;
pair<ll,ll> pii[400006];
ll sum[400006];
void init()
{
	for(int i=1;i<=n;++i)
	{
		ll a,b;
		cin>>a>>b;
		pii[++t].first=a;
		pii[t].second=1;
		pii[++t].first=b+1;
		pii[t].second=-1;
	}
	sort(pii+1,pii+1+t);
}
void solve()
{
	int cnt=0;
	for(int i=1;i<=t;++i)
	{
		cnt+=pii[i].second;
		if(pii[i].first!=pii[i+1].first)sum[cnt]+=pii[i+1].first-pii[i].first;
	}
}
int main()
{
	cin>>n;
	init();
	solve();
	cout<<sum[1];
	for(int i=2;i<=n;++i)
	{
		cout<<" "<<sum[i];
	}
	return 0;
}

洛谷P3406:海底高铁
题不难(虽然我因为粗心wa了3发,哎,菜鸡本菜)题目长或输入花里胡哨啥的虽然恶心但是不要慌,主要是架构思路,如果这道题你是没看题解写出来的,那比起一开始初学算法你已经上升了一个阶段了,当然如果看了也没关系,大家都是这么过来的,会变强的。
思路:桶排+差分
(我的第一发WA,以为起点从1开始,🤮)
预处理:用一个变量last记录起点,然后认识到1到3和3到1是一样的,即可成功构造出差分数组(反正都是小的+1大的数+1后的区间-1)。ok,那么我们现在手里就有了从每个站到另1个站的次数。
判断买不买卡:(设原价为a,打折价为b,卡价为c)
情况1:a>b+c,傻子才不买
情况2:a<b[i]*(a-b)+c,当满足这种情况时买卡就血赚,省下的钱就可以拿去氪金了,开心
相等的话就无所谓了
好了这时我又死在了另一个坑(那就是如果不经过某一个站,就不用买卡,WA了2发)ok了,上代码

#include<iostream>
#define ll long long int
#define M 100006
using namespace std;
int n,m,b[M],arr[M],last;
ll ans,card;
int main() {
	ios::sync_with_stdio(false);
	cin>>n>>m;
	cin>>last;
	for(int i=1; i<=m-1; ++i) {
		int d;
		cin>>d;
		if(last<d) {
			b[last]+=1;
			b[d]-=1;
		}
		else{
			b[d]+=1;
			b[last]-=1;
		}
		last=d;
	}
	for(int i=1;i<=n-1;++i){b[i]+=b[i-1];}
	ll a,d,c;
	for(int i=1;i<=n-1;++i)
	{
		cin>>a>>d>>c;
		if(a>(d+c)&&b[i]){
			card+=c;
			ans+=b[i]*d;
		}
		else if(c<(a-d)*b[i]&&b[i]){
			card+=c;
			ans+=b[i]*d;
		}
		else{
			ans+=b[i]*a;
		}
	}
	cout<<ans+card;
}

cWing796二维前缀和
我好累啊!!!这个自己去大佬博客上看吧,不想写了

#include<iostream>
#define M 100006
using namespace std;
int arr[1002][1002],n,m,k,sum;
int main()
{
    ios::sync_with_stdio(false);
   cin>>n>>m>>k;
   for(int i=1;i<=n;++i)
   for(int j=1;j<=m;++j)
   {
   		cin>>arr[i][j];
   		arr[i][j]+=arr[i-1][j]+arr[i][j-1]-arr[i-1][j-1];
   }
   for(int i=1;i<=k;++i)
   {
   		int l1,r1,l2,r2;
   		cin>>l1>>r1>>l2>>r2;
   		sum=arr[l2][r2]-arr[l2][r1-1]-arr[l1-1][r2]+arr[l1-1][r1-1];
   		cout<<sum<<'\n';
   }
}

AcWing798二维差分
同上,自己去看吧,大佬表达的会比我好的多

#include<iostream>
#define M 100006
using namespace std;
int arr[1002][1002],b[1002][1002],n,m,k,sum;
int main()
{
    ios::sync_with_stdio(false);
   cin>>n>>m>>k;
   for(int i=1;i<=n;++i)
   for(int j=1;j<=m;++j)
   {
   		cin>>arr[i][j];
   }
   for(int i=1;i<=k;++i)
   {
   		int l1,r1,l2,r2,c;
   		cin>>l1>>r1>>l2>>r2>>c;
   		b[l1][r1]+=c;
   		b[l1][r2+1]-=c;
   		b[l2+1][r1]-=c;
   		b[l2+1][r2+1]+=c;
   }
   for(int i=1;i<=n;++i)
   {
		for(int j=1;j<=m;++j)
   		{
   			b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
   			arr[i][j]+=b[i][j];
   			if(j==1)cout<<arr[i][j];
   			else cout<<' '<<arr[i][j];
   		}
		cout<<'\n';
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值