单峰数列
题意:
对于一个整数数列,如果其先严格递增,然后在某一点后严格递减,我们称这个数列为单峰数列(严格递增和严格递减的部分均要是非空)。1<=n<=1e5,1<=a[i]<=1e9,1<=q<=1e5。
[l,r]都加上x,[l,r]是否全部相同,[l,r]是否为严格升序,[l,r]是否为严格降序,[l,r]是否为单峰数列。
思考:
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define PII pair<int,int >
#define int long long
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define node_l node<<1
#define node_r node<<1|1
using namespace std;
const int N = 1e5+10,mod = 998244353;
struct Node{
int l,r;
int minn,maxn;
int laz;
int up;
int down;
}t[4*N];
int n,m;
int va[N];
void pushdown(int node)
{
int laz = t[node].laz;
if(laz!=0)
{
t[node_l].laz += laz;
t[node_l].minn += laz;
t[node_l].maxn += laz;
t[node_r].laz += laz;
t[node_r].minn += laz;
t[node_r].maxn += laz;
t[node].laz = 0;
}
}
void pushup(int node)
{
t[node].minn = min(t[node_l].minn,t[node_r].minn);
t[node].maxn = max(t[node_l].maxn,t[node_r].maxn);
int up = 0;
up += t[node_l].up;
up += t[node_r].up;
up += (t[node_l].maxn<t[node_r].minn);
int down = 0;
down += t[node_l].down;
down += t[node_r].down;
down += (t[node_l].minn>t[node_r].maxn);
t[node].up = (up==3);
t[node].down = (down==3);
}
void build(int node,int l,int r)
{
t[node].l = l,t[node].r = r;
if(l==r)
{
t[node].minn = va[l];
t[node].maxn = va[l];
t[node].up = 1;
t[node].down = 1;
return ;
}
int mid = (t[node].l+t[node].r)>>1;
build(node_l,l,mid);
build(node_r,mid+1,r);
pushup(node);
}
void update(int node,int l,int r,int value)
{
if(t[node].l>r||t[node].r<l) return;
if(t[node].l>=l&&t[node].r<=r)
{
t[node].laz += value;
t[node].minn += value;
t[node].maxn += value;
return ;
}
pushdown(node);
int mid = (t[node].l+t[node].r)>>1;
if(l<=mid) update(node_l,l,r,value);
if(r>mid) update(node_r,l,r,value);
pushup(node);
}
int queryminn(int node,int l,int r)
{
if(t[node].l>r||t[node].r<l)
{
return 1e18;
}
if(t[node].l>=l&&t[node].r<=r)
{
return t[node].minn;
}
pushdown(node);
int mid = (t[node].l+t[node].r)>>1;
if(r<=mid) return queryminn(node_l,l,r);
else if(l>mid) return queryminn(node_r,l,r);
else return min(queryminn(node_l,l,mid),queryminn(node_r,mid+1,r));
pushup(node);
}
int querymaxn(int node,int l,int r)
{
if(t[node].l>r||t[node].r<l)
{
return -1e18;
}
if(t[node].l>=l&&t[node].r<=r)
{
return t[node].maxn;
}
pushdown(node);
int mid = (t[node].l+t[node].r)>>1;
if(r<=mid) return querymaxn(node_l,l,r);
else if(l>mid) return querymaxn(node_r,l,r);
else return max(querymaxn(node_l,l,mid),querymaxn(node_r,mid+1,r));
pushup(node);
}
int queryup(int node,int l,int r)
{
if(t[node].l>=l&&t[node].r<=r)
{
return t[node].up;
}
pushdown(node);
int mid = (t[node].l+t[node].r)>>1;
if(r<=mid) return queryup(node_l,l,r);
else if(l>mid) return queryup(node_r,l,r);
else
{
int suc = 0;
suc += queryup(node_l,l,mid);
suc += queryup(node_r,mid+1,r);
suc += (querymaxn(node_l,l,mid)<queryminn(node_r,mid+1,r));
return (suc==3);
}
pushup(node);
}
int querydown(int node,int l,int r)
{
if(t[node].l>=l&&t[node].r<=r)
{
return t[node].down;
}
pushdown(node);
int mid = (t[node].l+t[node].r)>>1;
if(r<=mid) return querydown(node_l,l,r);
else if(l>mid) return querydown(node_r,l,r);
else
{
int suc = 0;
suc += querydown(node_l,l,mid);
suc += querydown(node_r,mid+1,r);
suc += (queryminn(node_l,l,mid)>querymaxn(node_r,mid+1,r));
return (suc==3);
}
pushup(node);
}
signed main()
{
IOS;
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i];
build(1,1,n);
cin>>m;
while(m--)
{
int op,l,r,x;
cin>>op>>l>>r;
if(op==1)
{
cin>>x;
update(1,l,r,x);
}
if(op==2)
{
if(queryminn(1,l,r)==querymaxn(1,l,r)) cout<<1<<"\n";
else cout<<0<<"\n";
}
if(op==3)
{
if(queryup(1,l,r)) cout<<1<<"\n";
else cout<<0<<"\n";
}
if(op==4)
{
if(querydown(1,l,r)) cout<<1<<"\n";
else cout<<0<<"\n";
}
if(op==5)
{
int L = l,R = r;
while(L<R)
{
int mid = (L+R+1)/2;
if(queryup(1,l,mid)) L = mid;
else R = mid-1;
}
int now = L;
if(now==l||now==r)
{
cout<<0<<"\n";
continue;
}
if(queryup(1,l,now)&&querydown(1,now,r)&&querymaxn(1,now,now)>queryminn(1,now+1,now+1)) cout<<1<<"\n";
else cout<<0<<"\n";
}
}
return 0;
}