[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(kn\sqrt{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\n",ans);
47     return 0;
48 }

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

猜你喜欢

转载自www.cnblogs.com/HocRiser/p/9049725.html