• [BZOJ 2653] middle


    [题目链接]

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

    [算法]

             显然 , 问题具有单调性 , 不妨对于每组询问首先二分答案mid

             将大于等于mid的数看作1 , 小于mid的数看作-1 , 问题转化为判断是否有左端点在[l1 , r1] , 右端点在[l2 , r2] , 区间和大于等于0的区间

             那么我们只要对于每个数建立线段树 , 维护向左 , 右延伸的最大子段和

             但是这样我们需要建立n棵线段树 , 显然是不可行的

             不难发现 , 第i棵线段树和第(i - 1)棵线段树相比只有一个元素的值不同

             将该过程可持久化即可

             时间复杂度 : O(NlogN ^ 2)

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define N 20010
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int inf = 1e9;
    
    struct info
    {
            int lmax , rmax , sum;
    } Ans;
    
    int n , q;
    int a[N] , perm[N] , rt[N];
    
    struct Presitent_Segment_Tree
    {
            int sz;
            int lc[N * 40] , rc[N * 40] , lm[N * 40] , rm[N * 40] , cnt[N * 40];
            Presitent_Segment_Tree()
            {
                    sz = 0;        
            }        
            inline void build(int &now , int l , int r)
            {
                    now = ++sz;
                    lm[now] = rm[now] = cnt[now] = r - l + 1;
                    if (l == r) return;
                    int mid = (l + r) >> 1;
                    build(lc[now] , l , mid);
                    build(rc[now] , mid + 1 , r);
            }
            inline void update(int now)
            {
                    lm[now] = max(lm[lc[now]] , cnt[lc[now]] + lm[rc[now]]);
                    rm[now] = max(rm[rc[now]] , cnt[rc[now]] + rm[lc[now]]);
                    cnt[now] = cnt[lc[now]] + cnt[rc[now]];
            }
            inline void modify(int &now , int old , int l , int r , int x , int value)
            {
                    now = ++sz;
                    lc[now] = lc[old] , rc[now] = rc[old];
                    if (l == r)
                    {
                            cnt[now] = lm[now] = rm[now] = value;
                            return;
                    }
                    int mid = (l + r) >> 1;
                    if (mid >= x) modify(lc[now] , lc[old] , l , mid , x , value);
                    else modify(rc[now] , rc[old] , mid + 1 , r , x , value);
                    update(now);
            }
            inline void merge(info &x , info y)
            {
                    info ret;
                    ret.lmax = max(x.lmax , x.sum + y.lmax);
                    ret.rmax = max(y.rmax , y.sum + x.rmax);
                    ret.sum = x.sum + y.sum;
                    x = ret;
            }
            inline void query(int now , int l , int r , int ql , int qr)
            {
                    if (l == ql && r == qr) 
                            merge(Ans , (info){lm[now] , rm[now] , cnt[now]});
                    else
                    {
                            int mid = (l + r) >> 1;
                            if (mid >= qr) query(lc[now] , l , mid , ql , qr);
                            else if (mid + 1 <= ql) query(rc[now] , mid + 1 , r , ql , qr);
                            else
                            {
                                    query(lc[now] , l , mid , ql , mid);
                                    query(rc[now] , mid + 1 , r , mid + 1 , qr);
                            }
                    }
            }
    } PST;
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline bool cmp(int x , int y)
    {
            return a[x] < a[y];
    }
    inline int query(int l1 , int r1 , int l2 , int r2 , int x)
    {
            int ret = 0;
            Ans = (info){-inf , -inf , 0};
            if (r1 + 1 <= l2 - 1) PST.query(rt[x] , 1 , n , r1 + 1 , l2 - 1);
            ret += Ans.sum;
            Ans = (info){-inf , -inf , 0};
            PST.query(rt[x] , 1 , n , l1 , r1);
            ret += Ans.rmax;
            Ans = (info){-inf , -inf , 0};
            PST.query(rt[x] , 1 , n , l2 , r2);
            ret += Ans.lmax;
            return ret;
    }
    
    int main()
    {
            
            read(n);
            for (int i = 1; i <= n; ++i) 
            {
                    read(a[i]);
                    perm[i] = i;
            }
            sort(perm + 1 , perm + n + 1 , cmp);
            PST.build(rt[1] , 1 , n);
            for (int i = 2; i <= n; ++i) PST.modify(rt[i] , rt[i - 1] , 1 , n , perm[i - 1] , -1);
            read(q);
            int lastans = 0;
            while (q--)
            {
                    int Q[4] , A , B , C , D;
                    read(A); read(B); read(C); read(D);
                    Q[0] = (A + lastans) % n + 1;
                    Q[1] = (B + lastans) % n + 1;
                    Q[2] = (C + lastans) % n + 1;
                    Q[3] = (D + lastans) % n + 1;
                    sort(Q , Q + 4);
                    int l = 1 , r = n , ans = 0;
                    while (l <= r)
                    {
                            int mid = (l + r) >> 1;
                            if (query(Q[0] , Q[1] , Q[2] , Q[3] , mid) >= 0)
                            {
                                    ans = a[perm[mid]];
                                    l = mid + 1;
                            } else r = mid - 1;
                    } 
                    printf("%d
    " , lastans = ans);
            }
             
            return 0;
        
    }
  • 相关阅读:
    Windows 编程入门,了解什么是UWP应用。
    java getway springcloud 记录请求数据
    nginx服务器配置传递给下一层的信息的一些参数-设置哪些跨域的域名可访问
    e.printStackTrace() 原理的分析
    关于性能测试组出现的问题查询和优化
    springboot connecting to :mongodb://127.0..0.1:27017/test authentication failed
    redis 集群 slots are covered by nodes.
    @PostConstruct +getapplicationcontext.getbean springboot获取getBean
    idea 错误: 找不到或无法加载主类 xx.xxx.Application
    elastic-job和spring cloud版本冲突2
  • 原文地址:https://www.cnblogs.com/evenbao/p/10623756.html
Copyright © 2020-2023  润新知