记录编号 570428 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI Online 2022 1st]丹钓战 最终得分 100
用户昵称 Gravatar遥时_彼方 是否通过 通过
代码语言 C++ 运行时间 3.564 s
提交时间 2022-03-31 18:31:43 内存使用 0.00 MiB
显示代码纯文本
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
using namespace std;
inline int read()
{
	int x=0;
	char a;
	a=getchar();
	while(a<'0'||a>'9') a=getchar();
	while(a>='0'&&a<='9') 
	{
		x=(x<<3)+(x<<1)+(a^48);
		a=getchar();
	}
	return x;
} 
int write(int x)
{
	if(x/10) write(x/10);
	putchar(x%10+48);
}
//////////////////////////////
const int MAXN=1e6+10;
int nc,qc;
int a[MAXN],b[MAXN];
int st[21][MAXN][2];//ST表(每个区间里的最小值的峰高及位置)
void BJ()
{
	int z[MAXN][2]={0};
	int cl=0;
	for(int i=1;i<=nc;i++)
	{
		while(z[cl][0]==a[i]&&cl!=0||z[cl][1]<=b[i]&&cl!=0) cl--;
		z[++cl][0]=a[i];
		z[cl][1]=b[i];
		st[0][i][0]=cl;
		st[0][i][1]=i; 
	}
	return;
}
void BUILD()
{
	for(int i=1,i2=1;i<=20;i++)
	{
		i2<<=1;
		for(int o=1;o+i2-1<=nc;o++)
		{
			if(st[i-1][o][0]<st[i-1][o+(i2>>1)][0])
			{
				st[i][o][0]=st[i-1][o][0];
				st[i][o][1]=st[i-1][o][1];
			} 
			else
			{
				st[i][o][0]=st[i-1][o+(i2>>1)][0];
				st[i][o][1]=st[i-1][o+(i2>>1)][1];
			}
		} 
	}
}
struct QXX
{
	int ar;
	int nx;
}g[MAXN<<1];
int gj;
int hd[MAXN];
int dep[MAXN];
inline void ADD(int x,int y)
{
	g[++gj].ar=y;
	g[gj].nx=hd[x];
	hd[x]=gj; 
	return;
}
void TREB()
{
	deque<int> t[2];//峰高和位置 
	for(int i=1;i<=nc;i++)
	{
		while(t[0].size()&&st[0][i][0]<=t[0].back())
		{
			ADD(i,t[1].back());
			t[0].pop_back();
			t[1].pop_back();
		}
		t[0].push_back(st[0][i][0]);
		t[1].push_back(i);
	}
	return;
}
void DFS(int cl,int de)
{
	dep[cl]=de;
	for(int i=hd[cl];i;i=g[i].nx) DFS(g[i].ar,de+1);
	return;
}
inline int MID(int x,int y)
{
	int re=0;
	int sum=y-x;
	while((1<<re)<=sum) re++;
	return re-1;
}
int main()
{
	freopen("noi_online2022_stack.in","r",stdin);
	freopen("noi_online2022_stack.out","w",stdout);
	nc=read();
	qc=read();
	for(int i=1;i<=nc;i++) a[i]=read();
	for(int i=1;i<=nc;i++) b[i]=read();
	BJ();//标记 
//	memset(st,0x3f,sizeof(st));
	BUILD();//建ST表
//	cout<<"P1\n";
	TREB();//树剖 
//	cout<<"P2\n";
	for(int i=nc;i;i--)
		if(!dep[i]){DFS(i,1);}//统计长度 
	int s1,s2,s3,ans;
//	cout<<"序号&&长度:\n";
//	for(int i=1;i<=nc;i++) cout<<i<<": "<<st[0][i][0]<<" "<<dep[i]<<endl;
//	cout<<"OV1\n";
	for(int i=1,sum;i<=qc;i++)
	{
		s1=read();
		s2=read();
		if(s1==s2)
		{
			printf("1");
			putchar(10);
			continue;
		}
// 		cout<<"CSS:"<<i<<":"<<s1<<" "<<s2<<endl;
		s3=MID(s1,s2);
		if(st[s3][s1][0]<st[s3][s2-(1<<s3)+1][0])
		{sum=st[s3][s1][1];}
		else
		{sum=st[s3][s2-(1<<s3)+1][1];}
		ans=dep[s1]-dep[sum]+1;
//		cout<<"CS:"<<sum<<" "<<s3<<" "<<st[s3][s1][0]<<" "<<st[s3][s2-(1<<s3)+1][0]<<"; "<<dep[s1]<<" "<<dep[sum]<<endl;
		write(ans);
		putchar(10);
	}
	return 0;
} 
//my 0
//ans 1