zoukankan      html  css  js  c++  java
  • NEUOJ 1702 撩妹全靠魅力值 (三维偏序)

    题目链接:http://acm.neu.edu.cn/hustoj/problem.php?id=1702

    题目大意:就是问每个人三个属性同时不低于另外几个人。。。。人不分先后

    经典的三维偏序问题

    解题思路:CDQ分治练手题

      1 #include<cstdio>
      2 #include<vector>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 int const MAX_Z=100000+5;
      8 int const MAX_N=100000+5;
      9 struct Ope{
     10     int x,y,z;
     11     int ty,id;
     12     Ope(int x,int y,int z,int ty,int id):x(x),y(y),z(z),ty(ty),id(id){}
     13     Ope(){}
     14 };
     15 
     16 bool cmp_x(Ope a,Ope b){
     17     if(a.x==b.x)return a.ty<b.ty;
     18     return a.x<b.x;
     19 }
     20 bool cmp_y(Ope a,Ope b){
     21     if(a.y==b.y)return a.ty<b.ty;
     22     return a.y<b.y;
     23 }
     24 
     25 vector<Ope> ope,ope2;
     26 //vector<int> allZ;
     27 vector<int>::iterator it;
     28 int tree[MAX_Z];
     29 int ans[MAX_Z];
     30 void add(int x,int a){
     31     while(x<MAX_Z){
     32         tree[x]+=a;
     33         x+=(x&(-x));
     34     }
     35 }
     36 
     37 int read(int x){
     38     int sum=0;
     39     while(x){
     40         sum+=tree[x];
     41         x-=(x&(-x));
     42     }
     43     return sum;
     44 }
     45 
     46 void work(){
     47     for(int i=0;i<ope2.size();i++){
     48         if(ope2[i].ty==0) add(ope2[i].z,1);
     49         else{
     50             int temp=read(ope2[i].z);
     51             ans[ope2[i].id]+=temp*ope2[i].ty;
     52         }
     53     }
     54     for(int i=0;i<ope2.size();i++)
     55         if(ope2[i].ty==0) add(ope2[i].z,-1);
     56 
     57 }
     58 
     59 void CDQ(int L,int R){
     60     if(L>=R)return;
     61     int mid=(L+R)>>1;
     62     CDQ(L,mid);
     63     ope2.clear();
     64     for(int i=L;i<=mid;i++){
     65         if(ope[i].ty==0)
     66             ope2.push_back(ope[i]);
     67     }
     68     for(int i=mid+1;i<=R;i++){
     69         if(ope[i].ty!=0)
     70             ope2.push_back(ope[i]);
     71     }
     72     sort(ope2.begin(),ope2.end(),cmp_y);
     73     work();
     74     CDQ(mid+1,R);
     75 }
     76 
     77 int main(){
     78     int T;
     79     int n;
     80     scanf("%d",&T);
     81     while(T--){
     82         scanf("%d",&n);
     83         ope.clear();
     84         //allZ.clear();
     85         memset(tree,0,sizeof(tree));
     86         memset(ans,0,sizeof(ans));
     87         for(int i=1;i<=n;i++){
     88             int x,y,z;
     89             scanf("%d%d%d",&x,&y,&z);
     90             ope.push_back(Ope(x,y,z,0,i));
     91             ope.push_back(Ope(x,y,z,1,i));
     92             //allZ.push_back(z);
     93         }
     94         /*
     95         sort(allZ.begin(),allZ.end());
     96         it=unique(allZ.begin(),allZ.end());
     97         allZ.resize(distance(allZ.begin(),it));
     98         for(int i=0;i<ope.size();i++){
     99             ope[i].z=lower_bound(allZ.begin(),allZ.end(),ope[i].z)-allZ.begin()+1;
    100         }
    101         */
    102         sort(ope.begin(),ope.end(),cmp_x);
    103         CDQ(0,ope.size()-1);
    104         for(int i=1;i<=n;i++){
    105             printf("%d
    ",ans[i]-1);
    106         }
    107     }
    108     return 0;
    109 }

    CDQ分治就是将前半截对后半截的影响拿出来,把偏序问题降维。

    三维的经过一次CDQ分治变成两维,四维的可以经过两次CDQ降成两维。

    两维偏序问题,一维排序,另一维做树状数组处理就可以。

    这里被注释掉的,是一种离散化的姿势,mark一下。

  • 相关阅读:
    0diff算法参考资料
    js 对象属性值
    一些带有设计模式的优秀代码
    vue 配置多页面
    cms 管理系统
    网络技术:EtherChannel 链路汇聚
    网络技术:VLAN 中继协议(VTP)
    网络管理:管理信息库
    网络管理:抽象语法表示 ASN.1
    网络管理:基本编码规则(BER)
  • 原文地址:https://www.cnblogs.com/xuwangzihao/p/5843513.html
Copyright © 2011-2022 走看看