社区讨论
所以到底能不能用主席树做
P1972[SDOI2009] HH 的项链参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @loc9ozfq
- 此快照首次捕获于
- 2023/10/30 10:14 2 年前
- 此快照最后确认于
- 2023/11/04 22:02 2 年前
RT,86分T两个点,都用了1.5S,卡不过去了。标签写着主席树,不知道是否加强数据后卡了
我的代码如下:
CPP#include <bits/stdc++.h>
#define mid ((l+r)>>1)
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch&15);ch=getchar();}
return x*f;
}
const int N=5e6+7,M=5e7+7;
int n,m,arr[N],last[N],Root[N];
int cnt;
struct TREE{int ls,rs,sum;}tree[M];
void update(int &NEW,int OLD,int l,int r,int val){//主席树维护last位置上数的数量,所以LR范围取0-n即可
NEW=++cnt;tree[NEW]=tree[OLD];tree[NEW].sum++;
if(l==r) return;
if(val<=mid) update(tree[NEW].ls,tree[OLD].ls,l,mid,val);
if(val>=mid+1) update(tree[NEW].rs,tree[OLD].rs,mid+1,r,val);
}
int query(int x,int y,int l,int r,int idx){
//拿维护每个last值数量的主席树,前缀和出区间权值线段树后,计算区间内有多少last<idx
//我只要减出来的树中维护的值域<idx的部分
if(l>=idx) return 0;
if(r<idx) return tree[y].sum-tree[x].sum;
return query(tree[x].ls,tree[y].ls,l,mid,idx)+query(tree[x].rs,tree[y].rs,mid+1,r,idx);
}
int main()
{
n=read();
for(int i=1;i<=n;i++) arr[i]=read(),update(Root[i],Root[i-1],0,n,last[arr[i]]),last[arr[i]]=i;
m=read();
int x,y;
for(int i=1;i<=m;i++){
x=read(),y=read();
printf("%d\n",query(Root[x-1],Root[y],0,n,x));
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...