zoukankan      html  css  js  c++  java
  • [ZJOI2013]K大数查询

    整体二分?

    二分答案c,求:

    solve(optl,optr,ansl,ansr);

    即work出操作在[ol,or],答案在[al,ar]?

    先搞出一个答案mid,再把opt扫一边。

    如果是1

    如果c>mid,就丢进树状数组里面。

    区间+1?

    三个树状数组的事情。

    然后把操作扔进右边QwQ

    如果c<=mid 就不管它

    然后把操作丢进左边。

    如果是2

    查询一下和。

    如果sum<k

    则意味着前面的操作里凑不出k个比mid大的数。

    则第k大一定比mid小。

    丢进左边。

    否则 丢进右边。

    然后

    solve(optl,sizel,ansl,mid);

    solve(sizel+1,optr,mid+1,ansr);

    直到l==r为止。

    上代码:

    //MADE BY BOBOYANG
    #include <bits/stdc++.h>
    #define LL long long int
    #define dob double
    using namespace std;
    const int N = 50010;
    struct Data{
      int type,l,r,c,id;
      bool operator <(const Data &a)const{
        return id<a.id;
      }
    }opt[N],que1[N],que2[N];
    int n,m,tim;LL Ans[N];
    struct BIT{
      LL A1[N],A2[N],A3[N];
      int vis1[N],vis2[N],vis3[N];
      inline int lb(int k){
        return k&-k;
      }
      inline void update(LL *A,int *vis,int x,int val){
        for(;x<=n;x+=lb(x)){
          if(vis[x]!=tim)A[x]=0;
          A[x]+=val;vis[x]=tim;
        }
      }
      inline LL query(LL *A,int *vis,int x,LL ans=0){
        for(;x;x-=lb(x)){
          if(vis[x]!=tim)A[x]=0;
          ans+=A[x];vis[x]=tim;
        }
        return ans;
      }
      inline void add(int l,int r,int dt){
        update(A2,vis2,l,dt);update(A2,vis2,r+1,-dt);
        update(A3,vis3,l,dt*l);update(A3,vis3,r+1,-dt*(r+1));
      }
      inline LL sum(int l,int r){
        LL sl=A1[l-1]+l*query(A2,vis2,l-1)-query(A3,vis3,l-1);
        LL sr=A1[r]+(r+1)*query(A2,vis2,r)-query(A3,vis3,r);
        return sr-sl;
      }
    }T;
    inline int gi(){
      int x=0,res=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
      while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
      return x*res;
    }
    inline void solve(int optl,int optr,int l,int r){
      if(optl>optr)return;++tim;
      if(l==r){
        for(int i=optl;i<=optr;++i)
          if(opt[i].type==2)
            Ans[opt[i].id]=l;
        return;
      }
      int mid=((l+r+2*n)>>1)-n,tot1=0,tot2=0;
      for(int i=optl;i<=optr;++i){
        if(opt[i].type==1){
          if(opt[i].c>mid){
            T.add(opt[i].l,opt[i].r,1);
            que2[++tot2]=opt[i];
          }
          else que1[++tot1]=opt[i];
        }
        else{
          LL sum=T.sum(opt[i].l,opt[i].r);
          if(sum<opt[i].c){
            opt[i].c-=sum;
            que1[++tot1]=opt[i];
          }
          else que2[++tot2]=opt[i];
        }
      }
      int k=optl;
      for(int i=1;i<=tot1;++i)opt[k++]=que1[i];
      for(int i=1;i<=tot2;++i)opt[k++]=que2[i];
      solve(optl,optl+tot1-1,l,mid);
      solve(optr-tot2+1,optr,mid+1,r);
    }
    int main()
    {
      n=gi();m=gi();
      for(int i=1;i<=m;++i){
        opt[i].type=gi();
        opt[i].l=gi();opt[i].r=gi();
        opt[i].c=gi();opt[i].id=i;
      }
      solve(1,m,-n,n);
      sort(opt+1,opt+m+1);
      for(int i=1;i<=m;++i)
        if(opt[i].type==2)
          printf("%lld
    ",Ans[i]);
      return 0;
    }
    
  • 相关阅读:
    小米路由通过SSH添加静态路由表之后无法跳转的问题
    极路由通过SSH添加静态路由表之后无法跳转的问题
    Linux服务器压测/拷机软件收集
    RabbitMQ整合Spring Booot【消费者补偿幂等问题】
    找不到共享解决办法
    如何一步步设计一款微服务的补偿方案
    Spring Cloud 支付宝支付的流程
    把同事的重复代码清理干净,老板却让我做了回滚?
    [LeetCode] 565. Array Nesting 数组嵌套
    [LeetCode] Out of Boundary Paths 出界的路径
  • 原文地址:https://www.cnblogs.com/zi-nai-boboyang/p/11437807.html
Copyright © 2011-2022 走看看