日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

四维偏序 CDQ套CDQ

發布時間:2023/12/10 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 四维偏序 CDQ套CDQ 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對CDQ深一步的理解

昨天做了一道CDQ,看了一堆CDQ可做的題,今天又做了一道四維偏序
感覺對CDQ的理解又深了一點,故來寫一寫現在自己對于CDQ的理解
CDQ其實就是實現了這樣的一個問題的轉化:
\(a_{l} < a_{l+1} < ... < a_r => (a_l,a_{l+1},...,a_{mid}) \text{都小于} (a_{mid+1},a{mid+2},...,a_r)\)
然后我們就知道這時候左邊所有的點都一定小于右邊的點
在四維偏序的算法中,那就是左邊的點可以對右邊的點做出貢獻(僅在當前維度下)
這樣就強行消除了一個維度的限制.

四維偏序

COGS 2479

題目大意

給定一個有\(n\)個元素的序列,元素編號為\(1~n\),每個元素有三個屬性\(a,b,c\),求序列中滿足\(i<j\)\(a_i<a_j\)\(b_i<b_j\)\(c_i<c_j\)的數對\((i,j)\)的個數。

題解

我們把下標也看作一個維度,那么這就是個四維偏序
我們在下標的維度上CDQ
然后記錄每個元素在第一次CDQ中是較小的還是較大的.
因為只有較小的元素才能對較大的元素做出貢獻
只有較大的元素才能接受較小的元素的影響.
所以我們處理出來后這就變成了一個三維偏序
所以我們在對這個序列(CDQ+掃描線+樹狀數組)求三維偏序即可

Code

#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; inline void read(int &x){x=0;char ch;bool flag = false;while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x; } const int maxn = 50010; struct Node{int a,b,c;bool is_sm;Node(){a=b=c=is_sm = 0;} }a[maxn],tmp1[maxn],tmp2[maxn]; int c[maxn],n,init_tmp[maxn],ans=0; #define lowbit(x) (x&-x) inline void modify(int x,int y){for(;x<=n;x+=lowbit(x)) c[x] += y; } inline int query(int x){int ret = 0;for(;x;x-=lowbit(x)) ret += c[x];return ret; } void solve2(int l,int r){if(l == r) return ;int mid = l+r >> 1;solve2(l,mid);solve2(mid+1,r);int i = l,j = mid+1,k = l;Node *a = tmp1,*tmp = tmp2;init_tmp[0] = 0;while(i <= mid || j <= r){if((j > r) || (i <= mid && a[i].b < a[j].b)){if( a[i].is_sm){modify(a[i].c,1);init_tmp[++init_tmp[0]] = i;}tmp[k++] = a[i++];}else{if(!a[j].is_sm){ans += query(a[j].c);}tmp[k++] = a[j++];}}for(int i = 1;i<=init_tmp[0];++i) modify(a[init_tmp[i]].c,-1);copy(tmp+l,tmp+r+1,a+l); } void solve1(int l,int r){if(l == r) return ;int mid = l+r >> 1;solve1(l,mid);solve1(mid+1,r);int i = l,j = mid+1,k = l;Node *tmp = tmp1;while(i <= mid || j <= r){if((j > r) || (i <= mid && a[i].a < a[j].a)){(tmp[k++] = a[i++]).is_sm = true;}else (tmp[k++] = a[j++]).is_sm = false;}copy(tmp+l,tmp+r+1,a+l);solve2(l,r); } int main(){ // freopen("partial_order.in","r",stdin); // freopen("partial_order.out","w",stdout);read(n);for(int i=1;i<=n;++i) read(a[i].a);for(int i=1;i<=n;++i) read(a[i].b);for(int i=1;i<=n;++i) read(a[i].c);solve1(1,n);printf("%d\n",ans);getchar();getchar();return 0; }

轉載于:https://www.cnblogs.com/Skyminer/p/6405323.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的四维偏序 CDQ套CDQ的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。