[COGS2479 && COGS2639]高维偏序(CDQ分治,bitset)

摘要:
CDQ集合CDQCDQ:划分并征服a,排序b,标记a,然后执行CDQ2CDQ2:划分和征服b,合并并排序c,排序d树数组。在每个小于当前一维的一维前面记录数字,最后取位集。阻塞减少了时间和空间的复杂性,两者都是$O$。

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)$暴力吧。

免责声明:文章转载自《[COGS2479 &amp;&amp; COGS2639]高维偏序(CDQ分治,bitset)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[九省联考2018]林克卡特树(DP+wqs二分)[BZOJ1790][AHOI2008]Rectangle 矩形藏宝地(四维偏序,CDQ+线段树)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

nyoj 115------城市平乱( dijkstra // bellman )

城市平乱 时间限制:1000ms | 内存限制:65535KB 难度:4 描述 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市。 他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M。 现在,小工军师告诉南将军,第K号城市发生了暴乱,南将军从各个部队都派遣了一个分队沿最近路去往暴乱城市平乱。 现在已知在任...

POJ3308 Paratroopers(网络流)(最小割)

Paratroopers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8443 Accepted: 2541 Description It is year 2500 A.D. and there is a terrible war between the...

NYOJ 45 棋盘覆盖

http://acm.nyist.net/JudgeOnline/problem.php?pid=45 刚开始没注意,是大数.... View Code 1 #include <stdio.h> 2 #include <string.h> 3 int ans[102][61]; 4 intmain() 5 { 6 int...

敌兵布阵 (树状数组&amp;线段树入门)

C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视。...

例7-4

#include<stdio.h> int main(void) { inti,index,n; int a[10]; printf("Enter n:"); scanf_s("%d",&n); printf("Enter %d integers:",n); for(i=0;i<n...

例4-8

#include<stdio.h> int main(void) { inti,mark,max,n; printf("Enter n:"); scanf("%d",&n); printf("Enter%d marks:",n); scanf("%d",&mark); max=...