1. 程式人生 > >●BZOJ BZOJ 4408 [Fjoi 2016]神秘數

●BZOJ BZOJ 4408 [Fjoi 2016]神秘數

ins space lld ont open span %d freopen long long

題鏈

http://www.lydsy.com/JudgeOnline/problem.php?id=4408
題解: 主席樹 首先,對於一些數來說, 如果可以我們可以使得其中的某些數能夠拼出 1~ret 那麽此時的ANS(神秘數)= ret+1 然後考慮,如果此時存在另一個數小於等於 ANS,(設該數為 x) 則一定可以在原來的1~ret的基礎上拼出 1~ret+x 即 ANS 可以更新為 ret+x+1 所以具體的操作就是: 每次查詢區間內小於ANS的數的和(SUM),然後如果SUM大於ANS,則更新ANS為SUM+1。 不斷上述操作直到SUM<ANS為止。
主席數實現在序列區間中查詢權值區間的和。 代碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100500
using namespace std;
int A[MAXN],tmp[MAXN];
int N,M,tnt;
struct CMT{
    long long sum[MAXN*20];
    int rt[MAXN],ls[MAXN*20],rs[MAXN*20],sz;
    void Insert(int v,int &u,int l,int r,int p){
        u=++sz; ls[u]=ls[v]; rs[u]=rs[v]; 
        sum[u]=sum[v]; sum[u]+=tmp[p];
        if(l==r) return;
        int mid=(l+r)>>1;
        if(p<=mid) Insert(ls[v],ls[u],l,mid,p);
        else Insert(rs[v],rs[u],mid+1,r,p);
    }
    long long Query(int v,int u,int l,int r,int al,int ar){
        if(al<=l&&r<=ar) return sum[u]-sum[v];
        int mid=(l+r)>>1; long long ret=0;
        if(al<=mid) ret+=Query(ls[v],ls[u],l,mid,al,ar);
        if(mid<ar) ret+=Query(rs[v],rs[u],mid+1,r,al,ar);
        return ret;
    }
    void Build(){
        for(int i=1;i<=N;i++)
            Insert(rt[i-1],rt[i],1,tnt,A[i]);
    }
}DT;
int main(){
//  freopen("/home/noilinux/Documents/Code/BZOJ/4408.in","r",stdin);
//  printf("BEGIN.\n");
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
        scanf("%d",&A[i]),tmp[i]=A[i];
    sort(tmp+1,tmp+N+1);
    tnt=unique(tmp+1,tmp+N+1)-tmp-1;
    for(int i=1;i<=N;i++)
        A[i]=lower_bound(tmp+1,tmp+tnt+1,A[i])-tmp;
    scanf("%d",&M);
    DT.Build(); long long ANS,ret,p;
    for(int i=1,l,r;ANS=0,ret=0,i<=M;i++){
        scanf("%d%d",&l,&r);
        while(ANS<ret+1){
            ANS=ret+1;
            p=upper_bound(tmp+1,tmp+tnt+1,ANS)-tmp-1;
            ret=DT.Query(DT.rt[l-1],DT.rt[r],1,tnt,1,p);
        }
        printf("%lld\n",ANS);
    }
    return 0;
}

  

●BZOJ BZOJ 4408 [Fjoi 2016]神秘數