論如何優雅的用bitset來求四維偏序
阿新 • • 發佈:2017-07-25
spa class 排序。 sam sin 判斷 clas 而且 ble
四維偏序。。
就是給你一個四維集合。再給你一些詢問,請你求出a[i].x1<=ask.x1&&a[i].x2<=ask.x2&&a[i].x3<=ask.x3&&a[i].x4<=ask.x4的個數。。
集合大小<=30000
詢問個數<=30000
然後怎麽做呢??
其實很簡單只要排序+cdq+樹狀數組套平衡樹什麽的就行了
qnmd老子不會。。
這時!
神器來了!
那就是bitset!
眾所周知,bitset能存一堆二進制位每一位的狀態,而且,bitset和bitset之間是可以進行&操作的
也就是說,我們每次可以對第i位排個序,在判斷第i個集合是否滿足詢問條件,bitset&一下就好了!
放上代碼
#include<cmath> #include<cstdio> #include<bitset> #include<algorithm> #define N 40000 #define eps 1e-8 using namespace std; int i,j,k,n,m,x,y,t; struct data{double x1,x2,x3,x4;int id,p;}p[N],q[N],pq[N+N]; bitset<N> ans[N],w; bool same(double a,double b){returnfabs(a-b)<eps;} bool cmp1(const data&a,const data&b){return same(a.x1,b.x1)?a.p>b.p:a.x1<b.x1-eps;} bool cmp2(const data&a,const data&b){return same(a.x2,b.x2)?a.p>b.p:a.x2<b.x2-eps;} bool cmp3(const data&a,const data&b){return same(a.x3,b.x3)?a.p>b.p:a.x3<b.x3-eps;}bool cmp4(const data&a,const data&b){return same(a.x4,b.x4)?a.p>b.p:a.x4<b.x4-eps;} int main(){ scanf("%d",&n); for (i=1;i<=n;i++){scanf("%lf%lf%lf%lf",&p[i].x1,&p[i].x2,&p[i].x3,&p[i].x4);p[i].id=i;p[i].p=1;} scanf("%d",&m); for (i=1;i<=m;i++){scanf("%lf%lf%lf%lf",&q[i].x1,&q[i].x2,&q[i].x3,&q[i].x4);q[i].id=i;q[i].p=0;} for (i=1;i<=m;i++)ans[i].set(); //----------------------------------------------------------------- for (i=1;i<=n;i++)pq[i]=p[i]; for (i=1;i<=m;i++)pq[n+i]=q[i]; sort(pq+1,pq+1+n+m,cmp1); w.reset(); for (i=1;i<=n+m;i++)if (pq[i].p)w[pq[i].id]=1;else ans[pq[i].id]&=w; //----------------------------------------------------------------- for (i=1;i<=n;i++)pq[i]=p[i]; for (i=1;i<=m;i++)pq[n+i]=q[i]; sort(pq+1,pq+1+n+m,cmp2); w.reset(); for (i=1;i<=n+m;i++)if (pq[i].p)w[pq[i].id]=1;else ans[pq[i].id]&=w; //----------------------------------------------------------------- for (i=1;i<=n;i++)pq[i]=p[i]; for (i=1;i<=m;i++)pq[n+i]=q[i]; sort(pq+1,pq+1+n+m,cmp3); w.reset(); for (i=1;i<=n+m;i++)if (pq[i].p)w[pq[i].id]=1;else ans[pq[i].id]&=w; //----------------------------------------------------------------- for (i=1;i<=n;i++)pq[i]=p[i]; for (i=1;i<=m;i++)pq[n+i]=q[i]; sort(pq+1,pq+1+n+m,cmp4); w.reset(); for (i=1;i<=n+m;i++)if (pq[i].p)w[pq[i].id]=1;else ans[pq[i].id]&=w; for (i=1;i<=m;i++)printf("%d\n",ans[i].count()); return 0; }
分隔符是為了分開四次排序。。
復雜度是O(n*m/32)....
盡管看上去很慢但是。。
論如何優雅的用bitset來求四維偏序