线段树求卡常

复杂度是没问题的,只不过毒瘤数据加上线段树常数有点大,好心人帮孩子卡一下常吧
题目:HH的项链

#include<bits/stdc++.h> 
using namespace std;
const int N=1e6+3;
int cnt,vcnt;
int n,m,a[N],b[N],root[N];
map<int,int> mp;
inline int read(){
	int f=1,x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();};
	while(s<='9'&&s>='0'){x=x*10+(s-'0');s=getchar();}
	return x*f;
} 
inline void write(int x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
    putchar('\n');
    return;
}
struct tree{
	int l,r,val;
}pst[N<<5];
int update(int pre,int pl,int pr,int x,int val){
	int rt=++cnt;
	pst[rt].l=pst[pre].l;
	pst[rt].r=pst[pre].r;
	pst[rt].val=pst[pre].val+val;
	//cout<<"pst:"<<pst[rt].val<<endl;	
	int mid=(pl+pr)>>1;
	if(pl<pr){
		if(x<=mid) pst[rt].l=update(pst[pre].l,pl,mid,x,val);
		else pst[rt].r=update(pst[pre].r,mid+1,pr,x,val);
	}
	return rt;
}
int query(int node,int pl,int pr,int l,int r){
	if(l<=pl&&pr<=r) return pst[node].val;
	int res=0,mid=(pl+pr)>>1;
	if(l<=mid) res+=query(pst[node].l,pl,mid,l,r);
	if(mid+1<=r) res+=query(pst[node].r,mid+1,pr,l,r);
	return res;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) {a[i]=read();}
	for(int i=n;i>=1;i--){
		if(mp[a[i]]){
			//cout<<"i:"<<i<<endl;
			//cout<<mp[a[i]]<<endl;
			root[i]=update(root[i+1],1,n,mp[a[i]],-1);//值改为0
			root[i]=update(root[i],1,n,i,1); 
		}
		else{
			root[i]=update(root[i+1],1,n,i,1);
		}
		mp[a[i]]=i;
	} 
	cin>>m;
	while(m--){
		int l,r;
		l=read();r=read();
		write(query(root[l],1,n,1,r)); 
		
	}
	return 0;
}
2 个赞

这题我写的莫队没卡过去,现在换成线段树还得卡

1 个赞


好险,差点没卡过去,
unordered_map好用的咧

1 个赞