• [BZOJ4408][FJOI2016]神秘数


    题目链接

    https://www.lydsy.com/JudgeOnline/problem.php?id=4408

    权限题

    题解

    首先我们考虑当区间[1..x]全部可以表达出来的时候,假设新加入一个数字K

    则如果K<=x+1 就表示从[1..x+K]中所有的数都可以被表示出来

    否则就gg了


    可是这个东西吧 它有多个区间 多个区间的话复杂度好像有点不对?

    考虑设ans=x,表示已经表达了[1..x]的所有数字

    y=Σa[i] i∈[l,r]且a[i]<=ans

    如果y<=ans 显然存在一个数字 k<=x+1

    否则表示其他所有数字都>x+1

    这个东西用一个主席树 离散化处理一下就行啦!

    #include <bits/stdc++.h>
    using namespace std;
    int Size,Siz,N,a[100005],b[100005],c[100005],rt[100005];
    struct Node{
        int l,r,val;
    }Tree[20*100005];
    int Get_Num(int x){
        int l=1,r=Size,ans;
        while (l<=r){
            int mid=(l+r)>>1;
            if (b[mid]<=x) ans=mid,l=mid+1;
            else r=mid-1;
        }
        return ans;
    }
    void Insert(int &rt1,int rt2,int l,int r,int Ned,int val){
        int mid=(l+r)>>1;
        rt1=++Siz;
        Tree[rt1]=Tree[rt2];
        Tree[rt1].val=Tree[rt2].val+val;
        if (l==r) return;
        if (Ned<=mid) Insert(Tree[rt1].l,Tree[rt2].l,l,mid,Ned,val);
        else Insert(Tree[rt1].r,Tree[rt2].r,mid+1,r,Ned,val);
    }
    int Query(int rt1,int rt2,int l,int r,int L,int R){
        int mid=(l+r)>>1;
        int ans=0;
        if (L<=l&&r<=R) return Tree[rt2].val-Tree[rt1].val;
        if (l<=mid) ans+=Query(Tree[rt1].l,Tree[rt2].l,l,mid,L,R);
        if (mid<R) ans+=Query(Tree[rt1].r,Tree[rt2].r,mid+1,r,L,R);
        return ans;
    }
    int main(){
        scanf("%d",&N);
        for (int i=1;i<=N;i++){
            scanf("%d",&b[i]);
            c[i]=b[i];
        }
        sort(b+1,b+N+1);
        Size=unique(b+1,b+N+1)-b-1;
        for (int i=1;i<=N;i++)
            a[i]=lower_bound(b+1,b+Size+1,c[i])-b;
        for (int i=1;i<=N;i++){
            rt[i]=rt[i-1];
            Insert(rt[i],rt[i-1],1,Size,a[i],c[i]);
        }
        int T;
        scanf("%d",&T);
        while (T--){
            int l,r;
            scanf("%d%d",&l,&r);
            int ans=1;
            while (1){
                int Ned=Get_Num(ans);
                int Sum=Query(rt[l-1],rt[r],1,Size,1,Ned);
                if (Sum>=ans) ans=Sum+1;
                else break;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    单独设置css的class属性
    理解闭包的使用方法
    npm常用命令和总结
    前端调试之服务器
    gulp 报错的处理——个人经验
    工作经验备忘
    c++:虚函数和纯虚函数(转载)
    snmp学习、配置
    sigar学习
    linux安装VSCode
  • 原文地址:https://www.cnblogs.com/si--nian/p/10957552.html
Copyright © 2020-2023  润新知