题解:P12448 [COTS 2025] 观草 / Trava
Solution
简单数据结构题。考虑上一些小套路。
将第一问的和式改为:
考虑稍微转化一下,设
这个怎么看呢,考虑记
由于只有
有一个小问题,你怎么处理初始的
复杂度
非常罕见的不是特别慢。
#include<bits/stdc++.h>
#define int long long
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=5e5+10;
int n,q,a[MAXN],t[MAXN<<2],V=2e9;
int tr[MAXN][2];
void Update(int pos,int v1,int v2) {
pos=n-pos+1;
while(pos<=n) tr[pos][0]+=v1,tr[pos][1]+=v2,pos+=pos&-pos;
return ;
}
pair<int,int> Query(int pos) {
int ans1=0,ans2=0;
pos=n-pos+1;
while(pos) ans1+=tr[pos][0],ans2+=tr[pos][1],pos-=pos&-pos;
return {ans1,ans2};
}
#define lson (k<<1)
#define rson (k<<1|1)
#define mid (l+r>>1)
void build(int k,int l,int r) {
if(l==r) return t[k]=a[l],void();
build(lson,l,mid),build(rson,mid+1,r);
return t[k]=max(t[lson],t[rson]),void();
}
int query(int k,int l,int r,int x,int y) {
if(x<=l&&r<=y) return t[k];
if(y<=mid) return query(lson,l,mid,x,y);
if(x>mid) return query(rson,mid+1,r,x,y);
return max(query(lson,l,mid,x,y),query(rson,mid+1,r,x,y));
}
void modify(int k,int l,int r,int pos,int v) {
if(l==r) return t[k]=v,void();
if(pos<=mid) modify(lson,l,mid,pos,v);
else modify(rson,mid+1,r,pos,v);
return t[k]=max(t[lson],t[rson]),void();
}
int bfind1(int k,int l,int r,int pos,int v) {
if(r<pos||t[k]<v) return -1;
if(l==r) return l;
int tans=bfind1(lson,l,mid,pos,v);
if(tans!=-1) return tans;
return bfind1(rson,mid+1,r,pos,v);
}
int bfind2(int k,int l,int r,int pos,int v) {
if(l>pos||t[k]<v) return -1;
if(l==r) return l;
int tans=bfind2(rson,mid+1,r,pos,v);
if(tans!=-1) return tans;
return bfind2(lson,l,mid,pos,v);
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>q;
ffor(i,1,n) cin>>a[i];
a[0]=a[n+1]=V,build(1,0,n+1);
stack<int> st; st.push(0);
ffor(i,1,n+1) {
while(!st.empty()&&a[i]>=a[st.top()]) {
int l=st.top()+1,r=i-1;
st.pop();
if(l<=r) Update(r-l+1,min(a[l-1],a[r+1])-query(1,0,n+1,l,r),(r-l+1)*(min(a[l-1],a[r+1])-query(1,0,n+1,l,r)));
}
if(!st.empty()) {
int l=st.top()+1,r=i-1;
if(l<=r) Update(r-l+1,min(a[l-1],a[r+1])-query(1,0,n+1,l,r),(r-l+1)*(min(a[l-1],a[r+1])-query(1,0,n+1,l,r)));
}
st.push(i);
}
ffor(i,1,q) {
char op;
int k;
cin>>op>>k;
if(op=='?') {
auto pr=Query(k);
cout<<V*(n-k+1)-(pr.second-(k-1)*pr.first)<<'\n';
}
else {
int L=bfind2(1,0,n+1,k,a[k]+1)+1,R=bfind1(1,0,n+1,k,a[k]+1)-1;
Update(R-L+1,-1,-(R-L+1));
if(L<=k-1) Update(k-L,1,k-L);
if(k+1<=R) Update(R-k,1,R-k);
a[k]++,modify(1,0,n+1,k,a[k]);
}
}
return 0;
}