[ABC353G] Merchant Takahashi
题目
考察:树状数组,线段树,动态规划。
题意简述:
有
-
1\le c\le 10^9 -
1\le t_i\le n -
1\le p_i\le 10^{13}
我们可以看出明显是一道 dp 题,然后
但是这样转移是
每个点造成的贡献是
- 当
x_i\ge x_j 时:\begin{aligned}c\times|x_i-x_j|&=c\times(x_i-x_j)\\&=c\times x_i-c\times x_j\end{aligned} - 当
x_i<x_j 时:\begin{aligned}c\times|x_i-x_j|&=c\times(x_j-x_i)\\&=c\times x_j-c\times x_i\end{aligned}
那么我们可以用树状数组或线段树维护
我们定义两个树状数组,
然后我们在修改
这样我们就可以在
代码:
#include<bits/stdc++.h>
#define int long long
#define inl inline
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define per(i,x,y) for(int i=x;i>=y;--i)
#define fst; ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
#define fi first
#define se second
#define INF LLONG_MAX
using namespace std;
const int N=2e5+5;
int n,c,m,t,p,num,ans;
struct BIT{
int a[N];
inl BIT(){
memset(a,-0x3f,sizeof(a));
}
inl int lowbit(int x){
return x&(-x);
}
inl void add(int x,int k){
while(x<=n){
a[x]=max(a[x],k);
x+=lowbit(x);
}
return;
}
inl int getmax(int x){
int mx=-INF;
while(x){
mx=max(mx,a[x]);
x-=lowbit(x);
}
return mx;
}
}t1,t2;
signed main(){
fst;
cin>>n>>c>>m;
t1.add(1,c);
t2.add(n,-c);
rep(i,1,m){
cin>>t>>p;
num=max(t1.getmax(t)-c*t,t2.getmax(n-t)+c*t)+p;
ans=max(ans,num);
t1.add(t,num+c*t);
t2.add(n-t+1,num-c*t);
}
cout<<ans;
return 0;
}