CF能过,洛谷全RE+TLE
查看原帖
CF能过,洛谷全RE+TLE
774854
qzmoot楼主2024/11/5 11:58
#include <bits/stdc++.h>
#define pb emplace_back
using namespace std;
const int N=4e5+5,B=650;
int n,q;
int a[N],id[N],idx;
bitset<N>vis;
vector<int>ts;
int las;
template<typename T>
void rd(T &x)
{
	x=0;
	char ch=getchar();
	while(ch<'0' && ch>'9')ch=getchar();
	while(ch>='0' && ch<='9')x=x*10+ch-48,ch=getchar();
}
template<typename T,typename... Args>
void rd(T &x,Args &... args)
{
	rd(x),rd(args...);
}
template<typename T>
void wr(T x)
{
	if(x<=9)
		putchar(x+48);
	else
		wr(x/10),putchar(x%10+48);
}
template<typename T>
void wrln(T x)
{
	wr(x),putchar('\n');
}
struct block{
	int l,r,f[B],fl;
	long long laz;
	void reset()
	{
		fl=1;
		for(int i=l;i<=r;i++)
		{
			if(id[a[i]]!=id[i])
				f[i-l]=i;
			else
				fl=0,f[i-l]=f[a[i]-l];
		}
	}
	void upd(int L,int R,int val)
	{
		for(int i=L;i<=R;i++)
			a[i]=i==1?0:max(a[i]-val,1);
		reset();
	}
	void upd(int val)
	{
		if(fl)laz+=val;
		else upd(l,r,val);
	}
}b[N/B+5];
void upd(int l,int r,int val)
{
	if(id[l]==id[r])
	{
		b[id[l]].upd(l,r,val);
		return;
	}
	b[id[l]].upd(l,b[id[l]].r,val);
	for(int i=id[l]+1;i<id[r];i++)
		b[i].upd(val);
	b[id[r]].upd(b[id[r]].l,r,val);
}
void clear()
{
	for(int i=0;i<ts.size();i++)
		vis[ts[i]]=0;
	ts.clear();
}
int lca(int x,int y)
{
	while(b[id[x]].f[x-b[id[x]].l]!=b[id[y]].f[y-b[id[y]].l])
	{
		if(id[x]<id[y])
			swap(x,y);
		x=(b[id[x]].f[x-b[id[x]].l]==1)?0:max(1ll,a[b[id[x]].f[x-b[id[x]].l]]-b[id[x]].laz);
	}
	int tar=(b[id[x]].f[x-b[id[x]].l]==1)?0:max(1ll,a[b[id[x]].f[x-b[id[x]].l]]-b[id[x]].laz);
	clear();
	while(x!=tar)
	{
		vis[x]=1;
		ts.pb(x);
		x=(x==1)?0:max(1ll,a[x]-b[id[x]].laz);
	}
	while(y!=tar)
	{
		if(vis[y])
			return y;
		y=(y==1)?0:max(1ll,a[y]-b[id[y]].laz);
	}
}
signed main()
{
	rd(n,q);
	for(int i=2;i<=n;i++)
		rd(a[i]);
	idx=(n-1)/B+1;
	for(int i=1;i<=idx;i++)
	{
		b[i].l=(i-1)*B+1,b[i].r=min(n,i*B);
		b[i].laz=b[i].fl=0;
		for(int j=b[i].l;j<=b[i].r;j++)
			id[j]=i;
	}
	vis.reset();
	for(int i=1;i<=idx;i++)
		b[i].reset();
	while(q--)
	{
		int op,x,y,z;
		rd(op,x,y);
		x^=las,y^=las;
		if(op==1)
			rd(z),z^=las,upd(x,y,z);
		else
			wrln(las=lca(x,y));
	}
	return 0;
}
2024/11/5 11:58
加载中...