Hdu5126 stars 兩次CDQ分治

2022-08-13 11:09:11 字數 1589 閱讀 5837

題意: 簡化就是有兩種操作,一種是插入(x,y,z)這個座標,第二種是查詢(x1,y1,z1)到(x2,y2,z2)(x1<=x2,y1<=y2,z1<=z2)的長方體包含多少個點。

解析: 將查詢分成8個點,離線做,離散化z值,

兩次cdq,第一次歸併排x值,第二次歸併排y值,z值用bit樹維護更新

查詢。**

#include#include

#include

#include

using

namespace

std;

const

int maxn=9*50000

;int

n,q,ans[maxn];

struct

node

}a[maxn],b[maxn],c[maxn];

//a儲存原陣列,b儲存中間過程,c用於歸併排序臨時陣列

bool cmpid(const node& a,const node& b)

void add(int i,int d)

int sum(int

i)void cdq2(int l,int r) //

歸併排y值,對z值查詢更新

if(b[rs].s!=0) ans[b[rs].id]+=sum(b[rs].z)*b[rs].s; //

右邊的是查詢

rs++;

}while(ls>l) //

恢復 ls=l,rs=mid+1

;

for(int i=l;i<=r;i++) //

歸併排序過程,排y值

for(int i=l;i<=r;i++) b[i]=c[i];

}void cdq1(int l,int r)//

歸併排x值,選取的過程是時序

if(k>0) cdq2(0,k-1); //

再一次cdq

ls=l,rs=mid+1

;

for(int i=l;i<=r;i++) //

歸併排序

for(int i=l;i<=r;i++) a[i]=c[i];

}int

main()

else

}memset(ans,

0,sizeof

(ans));

sort(a,a+n,cmpz); //

按照z值排序

int ka=1

; a[n].z=-1

;

for(int i=0;i)

if(a[i].z!=a[i+1].z) a[i].z=ka++; //

離散化else a[i].z=ka;

sort(a,a+n,cmpid); //

按照時序排回來

memset(tree,0,sizeof

(tree));

cdq1(

0,n-1

); sort(a,a+n,cmpid); //

再排回來

for(int i=0;i//

輸出答案

}return0;

}

view code

HDU 3400 兩次三分

這道題卡了我好久,一直不能證明他們的距離為什麼是先遞減後遞增,所以也不能想到三分 網上也沒有給出證明,嘗試用三分寫了下,注意是三分的e,f點在ab cd點上的佔的比例,這樣 比較簡單好看 include include include define eps 1e 8 struct point poi...

HDU 2612 Find a way(兩次廣搜)

分析這道題直接兩次bfs,累加兩個人分別到達同一kfc的最短時間,然後遍歷找到到達所有kfc時間之和最小的位置。注意如果時間為0,說明沒有到達過。include include include includeusing namespace std define inf 0x3f3f3f3f cons...

hdu 1254 推箱子(兩次廣搜)

這題乙個下午了,現在終於過了 用了兩次廣搜,一次搜箱子到目標地,第二次搜人是可以到推動箱子的地方,要注意的是箱子可能會阻擋人,也可以來回的推。給幾組資料就知道了 這題資料都是後面討論版中提供的 4 30 0 0 0 0 1 0 2 3 1 4 1 5 50 3 0 0 0 1 0 1 4 0 0 0...