WA*2,求调
查看原帖
WA*2,求调
700106
Xdik楼主2024/11/10 21:50

思路是主席树,维护可以i到n对前面每个点做的贡献,每次二分出可以看到这个点的点的区间,然后加起来

code:

#include <bits/stdc++.h>
//#define int long long
#pragma GCC optimeze(3)
#pragma GCC optimeze(2)
#define PII pair<int, int>
#define pb push_back
#define fi first
#define se second
#define lowbit(x) (x & (-x))
using namespace std;
const int N=2e5+5;
const int M=N*100; 
const int mod=1e9+7; 
//const int INF=1e10;
const int base=131;
int read() {
  int x=0,w=1;
  char ch=0;
  while(ch<'0'||ch>'9'){ 
    if (ch=='-')w=-1;     
    ch=getchar();               
  }
  while(ch>='0'&&ch<='9') { 
    x=x*10+(ch-'0'); 
    ch=getchar(); 
  }
  return x*w;
}
void write(int x) {
  static int sta[35];
  int top = 0;
  do {
    sta[top++] = x % 10, x /= 10;
  } while (x);
  while (top) putchar(sta[--top] + 48);
}
int qpow(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans*=a,ans%=mod;
		a=a*a,a%=mod;
		b>>=1;
	} 
	return ans;
}
int gcd(int x,int y){
	return y==0? x:gcd(y,x%y);
}
int n,h[N],tot,root[N],ls[M],rs[M],tr[M],st[19][N]; 
void init(){
	for(int i=1;i<=n;i++)st[0][i]=h[i];
	for(int i=1;i<=18;i++){
		for(int j=1;j+(1<<i)<=n;j++){
			st[i][j]=max(st[i-1][j],st[i-1][j+(1<<(i-1))]);
		}
	}
}
int qu(int l,int r){
	int k=log(r-l+1)/log(2); 
	return max(st[k][l],st[k][r-(1<<k)+1]); 
}
void add(int&p,int q,int x,int s,int t){
	p=++tot;
	tr[p]=tr[q]+1,ls[p]=ls[q],rs[p]=rs[q];
	if(s==t)return;
	int mid=(s+t)>>1;
	if(mid>=x)add(ls[p],ls[p],x,s,mid);
	else add(rs[p],rs[p],x,mid+1,t);
}
int ask(int l,int r,int p,int s,int t){
	if(s>=l&&t<=r)return tr[p];
	if(!p)return 0;
	int mid=(s+t)>>1,ans=0;
	if(mid>=l)ans+=ask(l,r,ls[p],s,mid);
	if(mid<r)ans+=ask(l,r,rs[p],mid+1,t);
	return ans;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int q;
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>h[i];
	init();
	root[n+1]=++tot;
	for(int i=n;i>=2;i--){
		if(h[i]<h[i-1]){
			root[i]=root[i+1];
			continue;
		}
		int l=1,r=i-1;
		while(l<r){
			int mid=(l+r)>>1;
			if(qu(mid,i)<=h[i])r=mid;
			else l=mid+1;
		}
		add(root[i],root[i+1],l,1,n);
	} 	
	while(q--){
		int l,r;
		cin>>l>>r;
		cout<<ask(1,l+1,root[r+1],1,n)<<'\n';
	}
	return 0;
}
2024/11/10 21:50
加载中...