分块离线求调qwq
查看原帖
分块离线求调qwq
264548
Tangent233楼主2022/9/9 21:56

离线算法理论上要用线段树,但我不太想打所以写了分块……明天还没人就写平衡树了

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10,blen=sqrt(maxn)+10;
int num[maxn];
int usen[maxn],cnt[blen][2],setn[blen];
int n,m,q;
inline int getb(int x)
{
	return (x-1)/blen+1;
}
void pushdown(int num)
{
	if(setn[num]==-1) return;
	for(int i=(num-1)*blen+1;i<=min(n,num*blen);i++)
		usen[i]=setn[num];
	setn[num]=-1;
}
void draw(int l,int r,int num)
{
	int bl=getb(l),br=getb(r);
	pushdown(bl);pushdown(br);
	for(int i=l;i<=min(r,bl*blen);i++)
	{
		cnt[bl][usen[i]]--;
		usen[i]=num;
		cnt[bl][num]++;
	}
	if(bl!=br)
	{
		for(int i=(br-1)*blen+1;i<=r;i++)
		{
			cnt[br][usen[i]]--;
			usen[i]=num;
			cnt[br][num]++;
		}
		for(int i=bl+1;i<=br-1;i++)
		{	
			setn[i]=num;
			cnt[i][!num]=0,cnt[i][num]=blen;
		}
	}
}
void sort1(int l,int r,int opt)
{
	int bl=getb(l),br=getb(r);
	int cnt1=0,cnt0=0;
	pushdown(bl),pushdown(br);
	for(int i=l;i<=min(r,bl*blen);i++)
		if(usen[i]==1) cnt1++;
		else cnt0++;
	if(bl!=br)
	{
		for(int i=(br-1)*blen+1;i<=r;i++)
			if(usen[i]==1) cnt1++;
			else cnt0++;
		for(int i=bl+1;i<=br-1;i++)
			cnt1+=cnt[i][1],cnt0+=cnt[i][0];
	}
	if(opt==1) draw(l,l+cnt1-1,1),draw(l+cnt1,r,0);
	else draw(l,l+cnt0-1,0),draw(l+cnt0,r,1);
}
int cao[maxn][4];
bool p(int x)
{
	for(int i=1;i<=getb(n);i++)
	{
		cnt[i][0]=cnt[i][1]=0;
		setn[i]=-1;
	}
	for(int i=1;i<=n;i++)
	{
		if(num[i]>=x) usen[i]=1;
		else usen[i]=0;
		cnt[getb(i)][usen[i]]++;
	}
	for(int i=1;i<=m;i++)
	{
		int opt=cao[i][1],l=cao[i][2],r=cao[i][3];
		sort1(l,r,opt);
	}
	pushdown(getb(q));
	return usen[q];
}
int ask(int l,int r)
{
	int ans=0;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(p(mid))
		{
			ans=mid;
			l=mid+1;
		}
		else r=mid-1;
	}
	return ans;
}
inline int read()
{
	int r=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){r=r*10+c-'0';c=getchar();}
	return r*f;
}
int main()
{
	//cin>>n>>m;
	
	n=read();m=read();
	for(int i=1;i<=n;i++) num[i]=read();
	for(int i=1;i<=m;i++)
		cao[i][1]=read(),cao[i][2]=read(),cao[i][3]=read();
	cin>>q;
	cout<<ask(1,n);
	return 0;
}
/*
1 6 2 5 3 4
6 5 2 1 3 4
6 5 
*/
2022/9/9 21:56
加载中...