信息
- ID
- 524
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 16
- 已通过
- 6
- 上传者
前人之述备矣,然则 set 换成 vector 可以跑0.5s
这样还是太慢了
比较斜率的时候可以用乘法做:
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
inline int Rd(){
int x=0,f=1; char c=getchar();
while (c<'0' || c>'9'){
if (c=='-') f=-1;
c=getchar();
}
while (c>='0'&&c<='9'){
x=(x<<1)+(x<<3)+(c^'0');
c=getchar();
}
return x*f;
}
int n,Q,a[2003],ans;
vector<int> st[2003];
inline void calc(int x){
st[x].clear();
for (int i=1;i<x;i++){
while (st[x].size() && 1ll*(a[x]-a[i])*(x-(*(st[x].end()-1))) < 1ll*(a[x]-a[*(st[x].end()-1)])*(x-i)){
st[x].erase(st[x].end()-1);
}
st[x].push_back(i);
}
}
int main(){
n=Rd();
for (int i=1;i<=n;i++){
a[i]=Rd();
calc(i);
}
Q=Rd();
for (int QQ=1;QQ<=Q;QQ++){
int x=Rd(),y=Rd(); a[x]+=y;
calc(x);
for (int i=x+1;i<=n;i++){
int r=lower_bound(st[i].begin(),st[i].end(), x)-st[i].begin();
if (st[i][r]!=x){
st[i].insert(st[i].begin()+r, x);
}
int l=r-1;
if (r+1==st[i].size() || 1ll*(a[i]-a[st[i][r]])*(i-st[i][r+1]) <= 1ll*(a[i]-a[st[i][r+1]])*(i-st[i][r])){
while (l>=0 && 1ll*(a[i]-a[st[i][r]])*(i-(st[i][l])) < 1ll*(a[i]-a[st[i][l]])*(i-(st[i][r]))) l--;
l++;
if (l!=r) st[i].erase(st[i].begin()+l,st[i].begin()+r);
}
else{
st[i].erase(st[i].begin()+r);
}
}
ans=0;
for (int i=1;i<=n;i++){
ans=ans+st[i].size();
}
printf("%d\n",ans);
}
return 0;
}