LUOGU P4587 [FJOI2016]神秘数(主席树)

传送门

解题思路

  如果区间内没有\(1\),那么答案就为\(1\),从这一点继续归纳。如果区间内有\(x\)\(1\),设区间内\([2,x+1]\)的和为\(sum\),如果\(sum=0\),那么答案为\(x+1\),否则\([1,x+sum]\)中的所有数字一定可以被表示,然后这个操作每次使答案至少扩大\(1\)倍,再用一个主席树维护,时间复杂度\(O(nlognlogA)\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;
const int N=100005;
const int M=N*33;
const int inf=1000000000;
typedef long long LL;

template<class T> void rd(T &x){
    x=0;char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
}   

int n,m,a[N],rt[N],ls[M],rs[M],sum[M],cnt;
LL Sum[M];

void build(int &x,int l,int r,int k){
    x=++cnt;
    if(l==r) {sum[x]=1;Sum[x]=l;return ;}
    int mid=(l+r)>>1;
    if(k<=mid) build(ls[x],l,mid,k);
    else build(rs[x],mid+1,r,k);
    Sum[x]=Sum[ls[x]]+Sum[rs[x]];
}

void update(int pre,int &x,int l,int r,int k){
    x=++cnt;ls[x]=ls[pre];rs[x]=rs[pre];
    if(l==r) {sum[x]=sum[pre]+1;Sum[x]=Sum[pre]+l;return;}int mid=(l+r)>>1;
    if(k<=mid) update(ls[pre],ls[x],l,mid,k);
    else update(rs[pre],rs[x],mid+1,r,k);
    Sum[x]=Sum[ls[x]]+Sum[rs[x]];
}

int query_tot(int u,int v,int l,int r,int k){
    if(l==r) return sum[v]-sum[u];
    int mid=(l+r)>>1;
    if(k<=mid) return query_tot(ls[u],ls[v],l,mid,k);
    else return query_tot(rs[u],rs[v],mid+1,r,k);   
}

LL query_sum(int u,int v,int l,int r,int L,int R){
    if(L<=l && r<=R) return Sum[v]-Sum[u];
    int mid=(l+r)>>1;LL ret=0;
    if(L<=mid) ret+=query_sum(ls[u],ls[v],l,mid,L,R);
    if(mid<R) ret+=query_sum(rs[u],rs[v],mid+1,r,L,R);
    return ret;
}

int main(){
    rd(n);rd(a[1]);build(rt[1],1,inf,a[1]);
    for(int i=2;i<=n;i++)
        rd(a[i]),update(rt[i-1],rt[i],1,inf,a[i]);
    rd(m);int l,r,now,k,tot,lst;
    while(m--){
        rd(l),rd(r);k=0;lst=0;
        while(1){
            now=query_sum(rt[l-1],rt[r],1,inf,lst,k+1);
            if(!now) break;lst=k+2;k=now+k;
        }
        printf("%d\n",k+1);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sdfzsyq/p/10254219.html