FJOI2016 神秘数

题目描述:

bz

luogu

题解:

没有多组询问的话非常好做。

先排个序,对小于等于当前总和+1的所有数求和,然后更新当前总和直到更新不了。

这题就是再套个主席树……

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100050;
const int M = 80*N;
const int inf = 1000000000;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
int n,m,rt[N];
struct pertree
{
    int tot,ls[M],rs[M];
    int w[M];
    void insert(int l,int r,int&u,int las,int qx)
    {
        u=++tot;ls[u]=ls[las],rs[u]=rs[las],w[u]=w[las]+qx;
        if(l==r)return ;
        int mid = (l+r)>>1;
        if(qx<=mid)insert(l,mid,ls[u],ls[las],qx);
        else insert(mid+1,r,rs[u],rs[las],qx);
    }
    int query(int l,int r,int L,int R,int ql,int qr)
    {
        if(!L&&!R)return 0;
        if(l==ql&&r==qr)return w[R]-w[L];
        int mid = (l+r)>>1;
        if(qr<=mid)return query(l,mid,ls[L],ls[R],ql,qr);
        else if(ql>mid)return query(mid+1,r,rs[L],rs[R],ql,qr);
        else return query(l,mid,ls[L],ls[R],ql,mid)+query(mid+1,r,rs[L],rs[R],mid+1,qr);
    }
}tr;
int main()
{
    read(n);
    for(int x,i=1;i<=n;i++)
        read(x),tr.insert(1,inf,rt[i],rt[i-1],x);
    read(m);
    for(int l,r,i=1;i<=m;i++)
    {
        read(l),read(r);
        int ans=1,tmp;
        while((tmp=tr.query(1,inf,rt[l-1],rt[r],1,ans))>=ans)
            ans=tmp+1;
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2019-06-28 09:30  LiGuanlin  阅读(155)  评论(0编辑  收藏  举报