洛谷 P3406 海底高铁(差分

P3406 海底高铁
基本思路:
对于其中一小段,我们要么全部买纸票,要么全部刷卡。

所以我们只需要统计每一小段经过的总次数。

如果你暴力模拟统计的话,估计(一定会tle。

接下来来看一组例子
六个数:
0 0 0 0 0 0
如果想让它从第二个到第五个数全部+1,则为
0 1 1 1 1 0
如果这样模拟+1,所用的时间复杂度为O(N)

如果记为
0 1 0 0 0 -1
所用时间复杂度为O(1)
每一位的值就是其前缀和
0 1 1 1 1 0

这是一维空间内的差分,对于二维空间的差分。

P3397 地毯
如下

0 0 0 0 0 0
0 +1 0 0 0 -1
0 +1 0 0 0 -1
0 +1 0 0 0 -1
0 +1 0 0 0 -1
0 0 0 0 0 0

#include <iostream>
#include <algorithm>
#include <cstring>
#include <math.h>
#include <functional>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <cstdio>
#include <list>
#include <queue>
#include <set>
#include <unordered_map>
#define ll long long
using namespace std;


int k[1100][1100];
int n,m;

int main(){
    cin>>n>>m;
    int i,a;
    int x1,y1,x2,y2;
    for(i=0;i<m;i++){
        cin>>x1>>y1>>x2>>y2;
        for(a=x1;a<=x2;a++){
            k[a][y1]++;
            k[a][y2+1]--;
        }
    }
    int s;
    for(i=1;i<=n;i++){
        s=0;
        for(a=1;a<=n;a++){
            s+=k[i][a];
            cout<<s<<" ";
        }
        cout<<endl;
    }
}

上文是关于什么是差分,差分相关思路。
我们可以看到,对于连续的一段数,加上或减去相同的数,通过差分处理可以比模拟更高效地完成任务。
这道题的代码如下:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <math.h>
#include <functional>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <cstdio>
#include <list>
#include <queue>
#include <set>
#include <unordered_map>
#define ll long long
using namespace std;


ll n,m;
ll k[100300];//各铁路段的次数(差分记录
ll num[100300];//路径
typedef struct{
    ll x,y,z;
}node;
node jo[100300];

int main(){
    cin>>n>>m;
    ll i;
    ll l,r;
    for(i=1;i<=m;i++) cin>>num[i];
    for(i=1;i<m;i++) {
        l=min(num[i],num[i+1]);
        r=max(num[i],num[i+1]);
        k[l]++;
        k[r]--;
    }
    for(i=1;i<n;i++){
        cin>>jo[i].x>>jo[i].y>>jo[i].z;
    }
    ll s=0;//总和
    ll price;//每一段的钱
    ll sum=0;//到目前为止的次数
    for(i=1;i<n;i++){
        sum+=k[i];
        price=min(jo[i].x*sum,jo[i].z+jo[i].y*sum);
        s+=price;
    }
    cout<<s;
}

遇事不决用long long
=-=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值