#主席树,fread,fwrite#洛谷 1972 [SDOI2009]HH的项链

题目


分析

维护每个位置的后继,问题转换为后继在区间外的位置的个数,
但是这题太卡常了,所以我就加了fread和fwrite
其实树状数组的解法我也写过了


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)
using namespace std;
const int N=1000101; char buf[1<<21],puf[1<<21],*p1,*p2; int nowp=-1;
inline signed iut(){
    rr int ans=0,f=1; rr char c=getchar();
    while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans*f;
}
inline void Flush(){fwrite(puf,1,nowp+1,stdout),nowp=-1;}
inline void Putchar(char x){
	if (nowp==(1<<21)) Flush();
	puf[++nowp]=x;
}
inline void print(int ans){
	rr char dig[21]; rr int len=-1;
	if (ans<0) Putchar('-'),ans=-ans;
	do{
		dig[++len]=ans%10+48,ans/=10; 
	}while (ans);
	while (len>=0) Putchar(dig[len--]);
}
struct Chair{
    int w[N<<5],ls[N<<5],rs[N<<5],cnt;
    inline void build(int &rt,int l,int r){
        w[rt=++cnt]=0; rr int mid=(l+r)>>1;
        if (l<r) build(ls[rt],l,mid),build(rs[rt],mid+1,r); 
    }
    inline void update(int &rt,int l,int r,int k){
        rr int trt=++cnt,mid=(l+r)>>1;
        ls[trt]=ls[rt],rs[trt]=rs[rt],w[trt]=w[rt]+1,rt=trt;
        if (l==r) return;
        k<=mid?update(ls[trt],l,mid,k):update(rs[trt],mid+1,r,k);
    }
    inline signed query(int L,int R,int l,int r,int k){
    	if (l==r) return w[R]-w[L];
    	rr int mid=(l+r)>>1;
    	if (k<=mid) return query(ls[L],ls[R],l,mid,k)+w[rs[R]]-w[rs[L]];
    	    else return query(rs[L],rs[R],mid+1,r,k);
    } 
}Tre;
int rt[N],n,m,k,las[N],a[N],nxt[N];
signed main(){
	n=iut();//Tre.build(rt[0],1,n+1);(这都能卡)
	for (rr int i=1;i<=n;++i) a[i]=iut();
	for (rr int i=1;i<=n;++i){
		if (las[a[i]]) nxt[las[a[i]]]=i;
		las[a[i]]=i;
	}
	for (rr int i=1;i<=n;++i) if (!nxt[i]) nxt[i]=n+1;
	for (rr int i=1;i<=n;++i) Tre.update(rt[i]=rt[i-1],1,n+1,nxt[i]);
	for (rr int m=iut();m;--m){
		rr int l=iut(),r=iut();
		print(Tre.query(rt[l-1],rt[r],1,n+1,r+1)),Putchar(10);
	}
	Flush();
    return 0;
}
原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14417584.html