线段树样例过不了求条
查看原帖
线段树样例过不了求条
728778
hdkk楼主2024/3/31 11:56
#include<bits/stdc++.h>
#define lc p*2+1
#define rc p*2+2
#define ll long long
#define mid ((l+r)>>1) 
using namespace std;
int a[300005];
struct node{
	int minn,tag,tag1;
	ll cnt,sum;
}tr[2000005];
struct Query{
	int l,r,id;
	ll ans;
}g[200005];
bool cmpp(Query r1,Query r2)
{
	return r1.r<r2.r;
}
bool cmpp1(Query r1,Query r2)
{
	return r1.id<r2.id;
}
void pushup(int p)
{
	if(tr[lc].minn<tr[rc].minn)
		tr[p].minn=tr[lc].minn,tr[p].cnt=tr[lc].cnt;
	if(tr[rc].minn<tr[lc].minn)	
		tr[p].minn=tr[rc].minn,tr[p].cnt=tr[rc].cnt;
	if(tr[rc].minn==tr[lc].minn)
		tr[p].minn=tr[lc].minn,tr[p].cnt=tr[lc].cnt+tr[rc].cnt; 
}
void pushdown(int p)
{
	if(tr[lc].minn==0)
	{
		tr[lc].sum+=tr[lc].cnt*tr[p].tag1;
		tr[lc].tag1+=tr[p].tag1;
	}
	if(tr[rc].minn==0)
	{
		tr[rc].sum+=tr[rc].cnt*tr[p].tag1;
		tr[rc].tag1+=tr[p].tag1;
	}
	tr[lc].minn+=tr[p].tag;
	tr[rc].minn+=tr[p].tag;
	tr[lc].tag+=tr[p].tag;
	tr[rc].tag+=tr[p].tag;
	tr[p].tag=0;
	tr[p].tag1=0;
}

void build(int l,int r,int p)
{
	if(l==r)
	{
		tr[p].minn=l;
		tr[p].cnt=1;
		return;
	}
	build(l,mid,lc);
	build(mid+1,r,rc);
	pushup(p);
}
void change(int l,int r,int ul,int ur,int p,int k)
{
	if(l>=ul&&r<=ur)
	{
		tr[p].minn+=k;
		tr[p].tag+=k;
		return;
	}
	pushdown(p);
	if(mid>=ul)
		change(l,mid,ul,ur,lc,k);
	if(mid<ur)
		change(mid+1,r,ul,ur,rc,k);
	pushup(p); 
}
void change1(int l,int r,int ul,int ur,int p)
{
	if(l>=ul&&r<=ur)
	{
		if(tr[p].minn==0)
		{
			tr[p].tag1++;
			tr[p].sum+=tr[p].cnt;
		}
		return;
	}
	//pushdown(p);
	if(mid>=ul)
		change1(l,mid,ul,ur,lc);
	if(mid<ur)
		change1(mid+1,r,ul,ur,rc); 
}
ll query(int l,int r,int ul,int ur,int p)
{
	//cout<<l<<' '<<r<<endl;
	if(l>=ul&&r<=ur)	
		return tr[p].sum;
	pushdown(p);
	ll ans=0;
	if(mid>=ul)
		ans+=query(l,mid,ul,ur,lc);
	if(mid<ur)
		ans+=query(mid+1,r,ul,ur,rc);
	return ans;
}
int s1[300005],s2[300005],st1,st2;
int main()
{
	int n,q;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		cin>>g[i].l>>g[i].r;
		g[i].id=i;
	}
	sort(g+1,g+1+q,cmpp);
	int xb=1;
	build(1,n,0);
	for(int i=1;i<=n;i++)
	{
		
		change(1,n,1,n,0,-1);
		while(st1&&a[s1[st1]]<a[i])
		{
			change(1,n,s1[st1-1]+1,s1[st1],0,a[i]-a[s1[st1]]);
			st1--;
		}
		s1[++st1]=i;
		while(st2&&a[s2[st2]]>a[i])
		{
			change(1,n,s2[st2-1]+1,s2[st2],0,a[s2[st2]]-a[i]);
			st2--;
		}
		change1(1,n,1,i,0);
		s2[++st2]=i;
		while(g[xb].r==i)
		{
			g[xb].ans=query(1,n,g[xb].l,i,0);
			//cout<<g[xb].l<<' '<<g[xb].r<<' '<<g[xb].ans<<endl;
			xb++;
		}
		//cout<<cntt.minn<<' '<<cntt.cnt;
	}
	sort(g+1,g+1+q,cmpp1);
	for(int i=1;i<=q;i++) cout<<g[i].ans<<endl;
 } 
2024/3/31 11:56
加载中...