[BZOJ4408][Fjoi 2016]神秘数(可持久化线段树)

题目描述

传送门

题解

首先考虑 O(mnlogn) 的做法
将询问的一段区间由小到大排序,假设现在已经用前k个数组合出了[1..x]中的所有整数,那么现在考虑加入第k+1个数
若k<=x+1,那么我们一定可以组合出[1..x+k]的所有整数,不会出现断层
若k>x+1,那么x+1这个整数是无论如何都无法组合的,就可以确定答案了

那么如果不排序有没有办法做呢?
同样假设当前已经组合好了[1..x],设ans=x+1;显然初始时x=0,ans=1
我们在区间[l,r]内统计一下权值<=ans的点的权值和,设为y。如果ans<=y,说明除了组合出[1..x]中的数,一定存在一个数满足<=x+1,这个时候[1..y]都可以组合出来,将ans移动到y+1;如果ans>y,说明除了组合出[1..x]的数,其余所有的数均>x+1,这样当前的ans就是答案了
统计一个区间内<=k的数的和可以用可持久化线段树来是实现
这样看起来很暴力,但其实ans每一次扩大至少扩大一倍,所以总时间复杂度为 O(mlognlogai)

代码

#include
#include
#include
#include
#include
using namespace std;
#define N 100005

int n,m,l,r,LSH,sz,ans;
int a[N],lsh[N],root[N],sum[N*20],ls[N*20],rs[N*20];

int find(int x)
{
    int l=1,r=LSH,mid,ans;
    while (l<=r)
    {
        mid=(l+r)>>1;
        if (lsh[mid]<=x) ans=mid,l=mid+1;
        else r=mid-1;
    }
    return ans;
}
void insert(int &now,int l,int r,int x,int val)
{
    int mid=(l+r)>>1;
    sum[++sz]=sum[now]+val;ls[sz]=ls[now];rs[sz]=rs[now];now=sz;
    if (l==r) return;
    if (x<=mid) insert(ls[now],l,mid,x,val);
    else insert(rs[now],mid+1,r,x,val);
}
int query(int L,int R,int l,int r,int lr,int rr)
{
    int mid=(l+r)>>1;
    int ans=0;
    if (lr<=l&&r<=rr) return sum[R]-sum[L];
    if (lr<=mid) ans+=query(ls[L],ls[R],l,mid,lr,rr);
    if (mid+1<=rr) ans+=query(rs[L],rs[R],mid+1,r,lr,rr);
    return ans;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;++i) scanf("%d",&a[i]),lsh[++LSH]=a[i];
    sort(lsh+1,lsh+LSH+1);LSH=unique(lsh+1,lsh+LSH+1)-lsh-1;
    for (int i=1;i<=n;++i)
    {
        int t=find(a[i]);
        root[i]=root[i-1];
        insert(root[i],1,LSH,t,a[i]);
    }
    scanf("%d",&m);
    for (int i=1;i<=m;++i)
    {
        scanf("%d%d",&l,&r);
        ans=1;
        while (1)
        {
            int t=find(ans);
            int sum=query(root[l-1],root[r],1,LSH,1,t);
            if (sum>=ans) ans=sum+1;
            else break;
        }
        printf("%d\n",ans);
    }
}

总结

这题作为胡策的c题竟然是最良心的一道
然而当时并没有a掉。。。

感觉上午的状态非常奇怪
简单的难的都想不出来
想出来的暴力不想打
硬gang代码题没gang出来

是该好好想想了。。。

你可能感兴趣的:(题解,数学相关,线段树,省选,可持久化)