zoukankan      html  css  js  c++  java
  • [COGS2479 && COGS2639]高维偏序(CDQ分治,bitset)

    COGS2479:四维偏序。

    CDQ套CDQ

    CDQ:对a分治,对b排序,再对a打标记,然后执行CDQ2

    CDQ2:对b分治,对c归并排序,对d树状数组。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=l; i<=r; i++)
     4 using namespace std;
     5 typedef long long ll;
     6 
     7 const int N=50010;
     8 int n,ans,c[N];
     9 struct P{ int a,b,c,d; bool flag; }a[N],t1[N],t2[N];
    10 
    11 void add(int p,int v){ for(;p<=n;p+=p&-p) c[p]+=v;}
    12 int sum(int p){ int re=0; for(;p;p-=p&-p) re+=c[p]; return re; }
    13 
    14 void CDQ2(int l,int r){
    15     if(l==r) return;
    16     int mid=(l+r)>>1;
    17     CDQ2(l,mid); CDQ2(mid+1,r);
    18     int i=l,j=mid+1,p=l;
    19     P *a=t1,*t=t2;
    20     while(i<=mid||j<=r){
    21         if(j>r||(i<=mid&&a[i].c<a[j].c)){
    22             if(a[i].flag) add(a[i].d,1);
    23             t[p++]=a[i++];
    24         }else{
    25             if(!a[j].flag) ans+=sum(a[j].d);
    26             t[p++]=a[j++];
    27         }
    28     }
    29     for(int i=l;i<=mid;i++) if(a[i].flag) add(a[i].d,-1);
    30     for(int i=l;i<=r;i++) a[i]=t[i];
    31 }
    32 
    33 void CDQ(int l,int r){
    34     if(l==r) return;
    35     int mid=(l+r)>>1;
    36     CDQ(l,mid);CDQ(mid+1,r);
    37     int i=l,j=mid+1,p=l;
    38     P *t=t1;
    39     while(i<=mid||j<=r){
    40         if(j>r||(i<=mid&&a[i].b<a[j].b)) (t[p++]=a[i++]).flag=1;
    41         else (t[p++]=a[j++]).flag=0;
    42     }
    43     for(int i=l;i<=r;i++) a[i]=t[i];
    44     CDQ2(l,r);
    45 }
    46 
    47 int main(){
    48     freopen("partial_order.in","r",stdin);
    49     freopen("partial_order.out","w",stdout);
    50     scanf("%d",&n);
    51     rep(i,1,n) scanf("%d",&a[i].b);
    52     rep(i,1,n) scanf("%d",&a[i].c);
    53     rep(i,1,n) scanf("%d",&a[i].d),a[i].a=i;
    54     CDQ(1,n); printf("%d",ans);
    55     return 0;
    56 }

    COGS2639 7维偏序。

    每一维记录前面的比当前这一维小的数个数,最后bitset取&就好了。

    分块降低时空复杂度,均为$O(knsqrt{n})$。

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <bitset>
     4 #include <algorithm>
     5 #define rep(i,l,r) for (int i=l; i<=r; i++)
     6 using namespace std;
     7 typedef long long ll;
     8 typedef bitset<40001>bit;
     9 
    10 const int N=40005;
    11 int n,k,size,block[N];
    12 
    13 struct Bitset{
    14     int a[N],lis[N];
    15     bit B[201];
    16     bit get(int p){
    17         p=a[p]; int bp=block[p]; bit ans=B[bp-1];
    18         for(int i=(bp-1)*size+1;i<p;i++) ans.set(lis[i]);
    19         return ans;
    20     }
    21 }d[7];
    22 
    23 void build(int op){
    24     rep(i,1,n) d[op].lis[d[op].a[i]]=i;
    25     bit t; t.reset();
    26     rep(i,1,n){
    27         t.set(d[op].lis[i]);
    28         if(i%size==0) d[op].B[i/size]=t;
    29     }
    30 }
    31 
    32 int main(){
    33     freopen("partial_order_plus.in","r",stdin);
    34     freopen("partial_order_plus.out","w",stdout);
    35     scanf("%d%d",&n,&k); size=sqrt(n);
    36     rep(i,1,n) block[i]=(i-1)/size+1;
    37     rep(i,1,n) d[0].a[i]=i;
    38     rep(i,1,k) rep(j,1,n) scanf("%d",&d[i].a[j]);
    39     rep(i,0,k) build(i);
    40     int ans=0;
    41     rep(i,1,n){
    42         bit t=d[0].get(i);
    43         rep(j,1,k) t&=d[j].get(i);
    44         ans+=t.count();
    45     }
    46     printf("%d
    ",ans);
    47     return 0;
    48 }

    更高维的偏序呢?$O(n^2)$暴力吧。

  • 相关阅读:
    python 3 day1(上)
    JMeter (一) Thread Group
    TC-001下载并简单使用Python
    SQL Server ->> 谈SQL Server数据库大表迁移
    SQL Server ->> 记Alwayson高可用副本同步失败后续恢复的性能调优争议
    SQL Server ->> AlwaysOn高可用副本同步失败
    SQL Server ->> AlwaysOn 监控脚本
    Linux ->> Source命令
    PSD 转化成 HTML
    笔试
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9049725.html
Copyright © 2011-2022 走看看