zoukankan      html  css  js  c++  java
  • BZOJ2773 : ispiti

    首先询问i相当于询问a[j]>=a[i],b[j]>=b[i]的j

    如果b[j]==b[i],那么a[j]>a[i],这种情况先用set处理掉

    如果b[j]>b[i],那么a[j]>=a[i],离散化后CDQ分治,用树状数组记录前缀最大值即可

    时间复杂度$O(nlog^2n)$

    #include<cstdio>
    #include<set>
    #include<algorithm>
    #define N 200010
    using namespace std;
    typedef pair<int,int> PI;
    int n,q,cnt,i,j,x,y,t1,t2,bit[N],pos[N],T,ans[N],L[N];
    char op;
    set<PI>Set[N];
    set<PI>::iterator it;
    struct P{int x,y,id;P(){}P(int _x,int _y,int _id){x=_x,y=_y,id=_id;}}a[N],b[N],c[N],stu[N];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline int lower(int x){
      int l=1,r=cnt,t,mid;
      while(l<=r)if(L[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    inline bool cmp(P a,P b){return a.x>b.x;}
    inline int merge(int x,int y){
      if(!x)return y;
      if(!y)return x;
      if(stu[x].y==stu[y].y)return stu[x].x<stu[y].x?x:y;
      return stu[x].y<stu[y].y?x:y;
    }
    inline void add(int x,int y){for(;x<=n;x+=x&-x)if(pos[x]<T)pos[x]=T,bit[x]=y;else bit[x]=merge(bit[x],y);}
    inline int ask(int x){int t=0;for(;x;x-=x&-x)if(pos[x]==T)t=merge(t,bit[x]);return t;}
    void solve(int l,int r){
      if(l==r)return;
      int mid=(l+r)>>1;
      solve(l,mid),solve(mid+1,r);
      for(t1=0,i=l;i<=mid;i++)if(a[i].id<0)b[t1++]=a[i];
      for(t2=0,i=r;i>mid;i--)if(a[i].id>0)c[t2++]=a[i];
      if(!t2)return;
      sort(b,b+t1,cmp),sort(c,c+t2,cmp);
      for(T++,i=j=0;i<t2;i++){
        while(j<t1&&b[j].x>=c[i].x)add(b[j].y,-b[j].id),j++;
        ans[c[i].id]=merge(ans[c[i].id],ask(c[i].y-1));
      }
    }
    int main(){
      read(n);
      for(i=1;i<=n;i++){
        while(!(((op=getchar())=='D')||(op=='P')));
        read(x);
        if(op=='D')read(y),L[++cnt]=y,stu[cnt]=a[i]=P(x,y,-cnt);else a[i]=stu[x],a[i].id=++q;
      }
      sort(L+1,L+cnt+1);
      for(i=1;i<=n;i++){
        a[i].y=cnt-lower(a[i].y)+1;
        if(a[i].id<0)Set[a[i].y].insert(PI(a[i].x,-a[i].id));
        else{
          it=Set[a[i].y].lower_bound(PI(a[i].x+1,0));
          if(it!=Set[a[i].y].end())ans[a[i].id]=it->second;
        }
      }
      solve(1,n);
      for(i=1;i<=q;i++)if(!ans[i])puts("NE");else printf("%d
    ",ans[i]);
      return 0;
    }
    

      

  • 相关阅读:
    hdu 5646 DZY Loves Partition
    bzoj 1001 狼抓兔子 平面图最小割
    poj 1815 Friendship 最小割 拆点 输出字典序
    spoj 1693 Coconuts 最小割 二者取其一式
    hdu 5643 King's Game 约瑟夫环变形
    约瑟夫环问题
    hdu 5642 King's Order
    CodeForces 631C Report
    1039: C语言程序设计教程(第三版)课后习题9.4
    1043: C语言程序设计教程(第三版)课后习题10.1
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403140.html
Copyright © 2011-2022 走看看