C,D c++ #雾粉与最小值# 通过单调栈获取已目前这位为最小的区间例如1 3 2,对于i=1,左边有0个<=a[i],右边有3个也就是对于len 1 2 3 的贡献都是1转换为三个等差数列,利用线段树维护,区间修改,区间查找 贡献类似于 1 2 2 2 1
1 2 3 3 2 1
1 2 1
1 1
1 这种
modify(1,len,r,0);
modify(1,r,1-r,1);
modify(len-r+1,len,0,-1);
对于获取的的区间,从大到小排好,离线处理val也从大到小,对于区间min>=val一个一个加进线段树,然后查询即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define N 510101
int n;
const int mod=1e9+7;
pair<int,int> st[N];
int cnt=0;
int l[N],r[N];
int a[N];
struct node3{
int w,le,re,id;
}p[N];
bool cmp3(node3 a,node3 b){
return a.w<b.w;
}
int m=0;
struct node2{
int w,l,r,dd;
int id;
}ans[N];
bool cmp1(node2 a,node2 b){
return a.w>b.w;
}
bool cmp2(node2 a,node2 b){
return a.id<b.id;
}
struct node {
int l, r;
int sum;
int k, d;
}t[N << 2];
int INV2 = mod - mod / 2;
int w[N];
void pushdown(node& op, int k, int d) {
// int len = op.r - op.l + 1;
// int qaq = (k + (k + 1ll * (len - 1) * d) % mod) % mod * len % mod * INV2 % mod;
// op.sum = (op.sum + qaq) % mod;
// op.k = (op.k + k) % mod, op.d = (op.d + d) % mod;
int len = op.r - op.l + 1;
int qaq = (k + (k + 1ll * (len - 1) * d) ) * len /2;
op.sum = (op.sum + qaq) ;
op.k = (op.k + k) , op.d = (op.d + d) ;
}
void pushdown(int x){
if (!t[x].k and !t[x].d) return;
pushdown(t[x << 1], t[x].k, t[x].d);
int llen = t[x << 1].r - t[x << 1].l + 1;
t[x].k = (t[x].k + 1ll * t[x].d * llen) ;
pushdown(t[x << 1 | 1], t[x].k, t[x].d);
t[x].k = t[x].d = 0;
}
void pushup(int x) { t[x].sum = (t[x << 1].sum + t[x << 1 | 1].sum) ; }
void build(int l, int r, int x = 1) {
t[x] = { l, r, w[l] , 0, 0 };
if (l == r) return;
int mid = l + r >> 1;
build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1);
pushup(x);
}
void modify(int l, int r, int k, int d, int x = 1) {
if (l <= t[x].l and r >= t[x].r) {
pushdown(t[x], k, d);
return;
}
pushdown(x);
int mid = t[x].l + t[x].r >> 1;
if (r <= mid) modify(l, r, k, d, x << 1);
else if (l > mid) modify(l, r, k, d, x << 1 | 1);
else {
modify(l, mid, k, d, x << 1);
k = (k + 1ll * d * (mid - l + 1)) ;
modify(mid + 1, r, k, d, x << 1 | 1);
}
pushup(x);
}
int ask(int l, int r, int x = 1) {
if (l <= t[x].l and r >= t[x].r) return t[x].sum;
pushdown(x);
int mid = t[x].l + t[x].r >> 1;
int res = 0;
if (l <= mid) res = ask(l, r, x << 1);
if (r > mid) res = (res + ask(l, r, x << 1 | 1)) ;
return res;
}
void solve() {
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,n);
for(int i=1;i<=n;i++){
if(a[i]<=st[cnt].first&&cnt!=0){
while(a[i]<=st[cnt].first&&cnt!=0){
r[st[cnt].second]=i;
cnt--;
i--;
}
continue;
}
if(a[i]>st[cnt].first&&cnt!=0){
l[i]=st[cnt].second;
st[++cnt]={a[i],i};
continue;
}
if(cnt==0){
l[i]=0;
st[++cnt]={a[i],i};
continue;
}
}
for(int i=1;i<=n;i++){
// cout<<l[i]<<' '<<r[i]<<'\n';
int j=i;
int le=l[i],re=r[j];
if(re==0) re=n+1;
int sum=re-le-1;
i=j;
p[++cnt].w=a[i];
p[cnt].le=le;
p[cnt].re=re;
p[cnt].id=i;
}
sort(p+1,p+cnt+1,cmp3);
int m=cnt;
int q;
cin>>q;
for(int i=1;i<=q;i++){
cin>>ans[i].w>>ans[i].l>>ans[i].r;
ans[i].id=i;
}
sort(ans+1,ans+q+1,cmp1);
int j=m;
for(int i=1;i<=q;i++){
//cout<<j<<'\n';
while(p[j].w>=ans[i].w&&j>=1){
int len=p[j].re-p[j].le-1;
int l=p[j].id-p[j].le-1,r=p[j].re-p[j].id;
modify(1,len,r,0);
modify(1,r,1-r,1);
modify(len-r+1,len,0,-1);
j--;
}
ans[i].dd=ask(ans[i].l,ans[i].r);
}
sort(ans+1,ans+q+1,cmp2);
for(int i=1;i<=q;i++){
cout<<ans[i].dd<<'\n';
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}