• HDU6601 Keep On EveryThing But Triangle(可持久化线段树)


    /*
     * hdu6601
     * 题意:
     * 给你一个长度为n的序列,有q个询问,每个询问给你一个区间[l,r],每次询问问你在区间[l,r]中,能够组成的最大的三角形的周长
     * 分析:
     * 因为三角形具有两边之和大于第三条边,利用这个性质,每次询问贪心的去枚举
     * 第k大,第k+1大,第k+2大去比较,如果不符合条件则继续向后找,时间复杂度(qlogn)
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn=4e5+10;
    int n,q,m,tot;
    int a[maxn];
    int t[maxn];
    int T[maxn];
    int lson[maxn*30],rson[maxn*30],c[maxn*30];
    void init_hash () {
        for (int i=1;i<=n;i++) t[i]=a[i];
        sort(t+1,t+n+1);
        m=unique(t+1,t+n+1)-t-1;
    }
    int build (int l,int r) {
        int root=tot++;
        c[root]=0;
        if (l!=r) {
            int mid=(l+r)>>1;
            lson[root]=build(l,mid);
            rson[root]=build(mid+1,r);
        }
        return root;
    }
    int Hash (int x) {
        return lower_bound(t+1,t+m+1,x)-t;
    }
    int update (int root,int pos,int val) {
        int newroot=tot++,tmp=newroot;
        c[newroot]=c[root]+val;
        int l=1,r=m;
        while (l<r) {
            int mid=(l+r)>>1;
            if (pos<=mid) {
                lson[newroot]=tot++;
                rson[newroot]=rson[root];
                newroot=lson[newroot];
                root=lson[root];
                r=mid;
            }
            else {
                rson[newroot]=tot++;
                lson[newroot]=lson[root];
                newroot=rson[newroot];
                root=rson[root];
                l=mid+1;
            }
            c[newroot]=c[root]+val;
        }
        return tmp;
    }
    int query (int left_root,int right_root,int k) {
        int l=1,r=m;
        while (l<r) {
            int mid=(l+r)>>1;
            if (c[lson[left_root]]-c[lson[right_root]]>=k) {
                r=mid;
                left_root=lson[left_root];
                right_root=lson[right_root];
            }
            else {
                l=mid+1;
                k-=c[lson[left_root]]-c[lson[right_root]];
                left_root=rson[left_root];
                right_root=rson[right_root];
            }
        }
        return l;
    }
    int main () {
        while (~scanf("%d%d",&n,&q)) {
            tot=0;
            for (int i=1;i<=n;i++) scanf("%d",&a[i]);
            init_hash();
            T[n+1]=build(1,m);
            for (int i=n;i;i--) {
                int pos=Hash(a[i]);
                T[i]=update(T[i+1],pos,1);
            }
            while (q--) {
                int l,r;
                scanf("%d%d",&l,&r);
                ll ans=-1;
                int k=(r-l+1);
                while (k>=3) {
                    ll x1=t[query(T[l],T[r+1],k)];
                    ll x2=t[query(T[l],T[r+1],k-1)];
                    ll x3=t[query(T[l],T[r+1],k-2)];
                    if (x1<x2+x3) {
                        ans=x1+x2+x3;
                        break;
                    }
                    k--;
                }
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    ASP.NET中彩票项目中的计算复式投注的注数的方法
    移除http响应中的多余的头(X-AspNet-Version,Server等)
    获取枚举类型的描述description
    支付宝支付后回调通知中responseTxt=true isSign=False可能的问题
    《JAVA与模式》之门面模式
    《JAVA与模式》之组合模式
    《JAVA与模式》之参考资料
    《JAVA与模式》之有感
    从桥接模式与策略模式谈起(转载)
    《JAVA与模式》之桥接模式
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12841048.html
Copyright © 2020-2023  润新知