主席树求助
查看原帖
主席树求助
278259
RemiliaScar1et楼主2021/2/25 20:35

如图,求差错 or Hack数据

/*
定义一个数组nxt[i]表示下一个与[i]相同贝壳的位置
给我们一个[l,r] , 我们每次要求l<=i<=r且nxt[i]>r的个数
主席树维护区间,在线处理询问
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=1e6+10;

struct node
{
	int lson,rson,val;
} tree[N*80];

ll root[N],tot=0;
int n,m;
int nxt[N],pre[N],poi[N];

#define lnode tree[node].lson
#define rnode tree[node].rson
#define DEFMID int mid=start+end>>1

int build(int start,int end)
{
	int node=++tot;
	if(start==end) return node;
	DEFMID;
	lnode=build(start,mid);
	rnode=build(mid+1,end);
	return node;
}

#define lnode1 tree[node1].lson
#define rnode1 tree[node1].rson

int update(int node,int start,int end,int val)
{
	int node1=++tot;
	tree[node1]=tree[node];
	if(start==end)
	{
		tree[node1].val++;
		return node1;
	}
	DEFMID;
	if(val<=mid) lnode1=update(lnode,start,mid,val);
	else rnode1=update(rnode,mid+1,end,val);
	
	tree[node1].val=tree[lnode1].val+tree[rnode1].val;
	return node1;
}

int query(int node1,int node,int start,int end,int l,int r)//node1-node
{
	if(end<l||start>r) return 0;
	if(l<=start&&end<=r) return tree[node1].val-tree[node].val;
	DEFMID;
	return query(lnode1,lnode,start,mid,l,r)+query(rnode1,rnode,mid+1,end,l,r);
}

#define rg register

inline void read(int &x)
{
	x=0;
	rg char ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
}

#undef rg

int main()
{
	read(n);
	for(int i=1;i<=n;++i)
		read(poi[i]);
	for(int i=n;i>=1;--i)//处理nxt数组
	{
		nxt[i]=(pre[poi[i]]?pre[poi[i]]:n+1);
		pre[poi[i]]=i;
	}
	root[0]=build(1,n+1);
	for(int i=1;i<=n;++i)
		root[i]=update(root[i-1],1,n+1,nxt[i]);
	read(m);
	for(int i=1;i<=m;++i)
	{
		int l,r;
		read(l); read(r);
		if(l>r) swap(l,r);
		int ans=query(root[r],root[l-1],1,n+1,r+1,n+1);
		printf("%d\n",ans);
	}
	return 0;
}
2021/2/25 20:35
加载中...