我不想玩原神。。。TLE16(线段树套线段树)

//应该是算法有问题,希望能帮我优化一下常数或者改进一下算法
寒假趣味做题 - 信友队
给定一个 n 行 n 列且值域为 [1,n] 的正整数方阵a 和 q 个询问。
每次询问给一个a的子矩阵的左上角坐标,右下角坐标,求子矩阵内的元素种类数
n=2000,q=500000

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define rc p<<1|1
#define lc p<<1
const int N=2010,c=0,K=61;
int n,a[N][N];
struct node
{
	ull a[N/K+10];
	int l,r;
};
struct tree
{
	node tr[N/8+10];
	int l,r;
};
tree s[2*N+10];
ull x[N/K+3];
void init(int idx,int p,int l,int r)
{
	s[idx].tr[p].l=l;
	s[idx].tr[p].r=r;
	if(r-l<=c)
	{
		int cnt;
		for(int i=l;i<=r;i++)
		{
			cnt=a[s[idx].l][i];
			s[idx].tr[p].a[cnt/K]|=(1ll<<(cnt%K));
		}
		return;
	}
	int mid=l+r>>1;
	init(idx,lc,l,mid);
	init(idx,rc,mid+1,r);
	for(int i=0;i<=N/K+1;i++)
	{
		s[idx].tr[p].a[i]=s[idx].tr[lc].a[i]|s[idx].tr[rc].a[i];
	}
	return;
}
void hb(int idx,int p,int l,int r)
{
	s[idx].tr[p].l=l;
	s[idx].tr[p].r=r;
	for(int i=0;i<=N/K+1;i++)
	{
		s[idx].tr[p].a[i]=s[idx<<1].tr[p].a[i]|s[idx<<1|1].tr[p].a[i];
	}
	if(s[idx].tr[p].r-s[idx].tr[p].l<=c)
	{
		return;
	}
	int mid=l+r>>1;
	hb(idx,lc,l,mid);
	hb(idx,rc,mid+1,r);
	return;
}
void build(int p,int l,int r)
{
	s[p].l=l;
	s[p].r=r;
	if(l==r)
	{
		init(p,1,1,n);
		return;
	}
	int mid=l+r>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	hb(p,1,1,n);
	return;
}
void uquery(int idx,int p,int l,int r)
{
	if(s[idx].tr[p].r<=r&&s[idx].tr[p].l>=l)
	{
		for(int i=0;i<=n/K+3;i++)
		{
			x[i]=x[i]|s[idx].tr[p].a[i];
		}
		return;
	}
	if(s[idx].tr[p].r-s[idx].tr[p].l<=c)
	{
		int cnt;
		for(int i=s[idx].l;i<=s[idx].r;i++)
		{
			for(int j=max(s[idx].tr[p].l,l);j<=min(r,s[idx].tr[p].r);j++)
			{
				cnt=a[i][j];
				x[cnt/K]|=(1ll<<(cnt%K));
			}
		}
		return;
	}
	int mid=s[idx].tr[p].l+s[idx].tr[p].r>>1;
	if(l<=mid)uquery(idx,lc,l,r);
	if(r>mid)uquery(idx,rc,l,r);
	return;
}
void query(int p,int x1,int y1,int x2,int y2)
{
	if(x1<=s[p].l&&s[p].r<=x2)
	{
		uquery(p,1,y1,y2);
		return;
	}
	int mid=s[p].l+s[p].r>>1;
	if(x1<=mid)query(lc,x1,y1,x2,y2);
	if(x2>mid)query(rc,x1,y1,x2,y2);
	return;
}
int main()
{
	freopen("genshin.in","r",stdin);
	freopen("genshin.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	build(1,1,n);
	int q;
	cin>>q;
	int l1,l2,r1,r2,ans;
	for(int i=1;i<=q;i++)
	{
		ans=0;
		for(int j=0;j<=N/K;j++)
		x[j]=0;
		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
		query(1,l1,l2,r1,r2);
		for(int j=0;j<=n+70;j++)
		{
			ans+=((x[j/K]|(1ll<<(j%K)))==x[j/K]);
		}
		printf("%d\n",ans);
	}
}

@王峥睿 看不到题目!

题目链接99%点不开的

(帖子已被作者删除)