zoukankan      html  css  js  c++  java
  • hdu6621 2019hdu多校4 线段树上乱搞

    http://acm.hdu.edu.cn/showproblem.php?pid=6621

    每个点维护该点内元素排序后的结果,每次寻味取出所有可能有解的区间

    对每个区间二分,得到一个ub,一个lb,然后双向遍历每个指针k轮,每次取出最小的值,然后移动一次指针

    第k轮得到的即为答案

    复杂度$O(nlogn(k+logn))$,后面的第二个logn很难跑满,而k又很大,所以最终复杂度大概是$O(knlogn)$

    #include<bits/stdc++.h>
    #define endl '
    '
    #define all(x) x.begin(),x.end()
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    #pragma GCC optimize("Ofast")
    const int maxn=1e5+8;
    using namespace std;
    int casn,n,m,k,a[maxn];
    class segtree{public:
    #define nd node[now]
    #define ndl node[now<<1]
    #define ndr node[now<<1|1]
      struct segnode {
        int l,r,len;
        vector<int> arr;
      }node[maxn<<2|3];
      void pushup(int now){
        nd.arr.clear();
        for(auto i:ndl.arr) nd.arr.push_back(i);
        for(auto i:ndr.arr) nd.arr.push_back(i);
        sort(all(nd.arr));
      }
      void maketree(int s,int t,int now=1){
        nd.l=s,nd.r=t,nd.len=t-s+1;
        if(s==t) {
          nd.arr.clear();
          nd.arr.push_back(a[s]);
          return ;
        }
        maketree(s,(s+t)>>1,now<<1);
        maketree((s+t)/2+1,t,now<<1|1);
        pushup(now);
      }
      vector<int> fd1,fd2;
      void query(int s,int t,int q,int now=1){
        if(s<=nd.l&&t>=nd.r) {
            if(nd.arr.back()>q) fd1.push_back(now);
            if(nd.arr[0]<=q) fd2.push_back(now);
            return ;
        }
        if(s<=ndl.r) query(s,t,q,now<<1);
        if(t>ndl.r) query(s,t,q,now<<1|1);
      }
      int solve(int q,int k){
            int la=fd1.size(),lb=fd2.size();
            vector<int> p1,p2;
            rep(i,0,la-1){
                int now=fd1[i];
                int pos=upper_bound(all(nd.arr),q)-nd.arr.begin();
                p1.push_back(pos);
            }
            rep(i,0,lb-1){
                int now=fd2[i];
                int pos=lower_bound(all(nd.arr),q)-nd.arr.begin();
                if(pos==nd.len||nd.arr[pos]>q) pos--;
                p2.push_back(pos);
            }
            int ans,id,flag;
            rep(i,0,k-1){
                ans=1e9,id=0,flag=0;
                rep(j,0,la-1){
                    int p=p1[j],now=fd1[j];
                    if(now==-1) continue;
                    if(nd.arr[p]-q<ans) ans=nd.arr[p]-q,id=j,flag=0;
                }
                rep(j,0,lb-1){
                    int p=p2[j],now=fd2[j];
                    if(now==-1) continue;
                    if(q-nd.arr[p]<ans) ans=q-nd.arr[p],id=j,flag=1;
                }
                if(flag==0){
                    p1[id]++;
                    if(p1[id]==node[fd1[id]].len) fd1[id]=-1;
                }else {
                    p2[id]--;
                    if(p2[id]==-1) fd2[id]=-1;
                }
            }
            return ans;
      }
    }tree;
    int main() {IO;
      cin>>casn;
      while(casn--){
        cin>>n>>m;
        rep(i,1,n) cin>>a[i];
        tree.maketree(1,n);
        int ans=0;
        while(m--){
          int l,r,a,k;cin>>l>>r>>a>>k;
          l^=ans,r^=ans,a^=ans,k^=ans;
          if(l>r) swap(l,r);
          tree.fd1.clear();tree.fd2.clear();
          tree.query(l,r,a);
          ans=tree.solve(a,k);
          cout<<ans<<endl;
        }
      }
    }
    
  • 相关阅读:
    Linux服务器基本信息查看
    Linxu下jenkins部署和基本配置
    Python常见序列详解
    Git 操作
    Python操作Mongodb
    sqlalchemy ORM模块使用介绍
    linux之sed的常用操作
    Python pandas学习笔记
    正则表达式——字符串匹配
    1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,...输入位置输出该位置上的数字,如输入10输出4,输入11输出5.
  • 原文地址:https://www.cnblogs.com/nervendnig/p/11279138.html
Copyright © 2011-2022 走看看