hdu4630 hdu4638 線段樹離線操作

2021-06-17 18:32:33 字數 1495 閱讀 3742

兩題都是樸素想法列舉兩個端點o(n^2)超時,那麼列舉其中乙個端點用線段樹維護另乙個端點。關鍵在於沒插入乙個端點後都是成段更新,否則又會退化到o(n^2)。

ps:兩題用c++交都比g++快500ms以上。

//#include#include#include#include#include#includeusing namespace std;

#define lson l,mid,rt<<1

#define rson mid+1,r,rt<<1|1

const int maxn=50005;

int tree[maxn<<2],lz[maxn<<2];

void pushdown(int rt)

void update(int l,int r,int val,int l,int r,int rt)

int mid=(l+r)>>1;

if(r<=mid)

if(l>mid)

pushdown(rt);

update(l,r,val,lson);

update(l,r,val,rson);

tree[rt]=max(tree[rt<<1],lz[rt<<1]);

tree[rt]=max(tree[rt],max(tree[rt<<1|1],lz[rt<<1|1]));

}int query(int l,int r,int l,int r,int rt)

int mid=(l+r)>>1;

pushdown(rt);

if(r<=mid)

if(l>mid)

return max(query(l,r,lson),query(l,r,rson));

}int a[maxn];

struct qyy

qyy(int a,int b,int c)

bool operator< (const qyy &a) const

void update(int l,int r,int val,int l,int r,int rt)

pushdown(rt);

int mid=(l+r)>>1;

if(r<=mid)

if(l>mid)

update(l,r,val,lson);

update(l,r,val,rson);

}int query(int pos,int l,int r,int rt)

int mid=(l+r)>>1;

pushdown(rt);

if(pos<=mid)

return query(pos,lson);

else

return query(pos,rson);

}bool hash[maxn];

int a[maxn];

struct qyy

qyy(int a,int b,int c)

bool operator< (const qyy& a) const

{return r

hdu 4638 Group 單點修改和離線線段樹

跟hdu4630如出一轍,但是思想上還是要有特別技巧 對於 l,r 上的數a i 我們給乙個標記mark i 表示第第i個數屬於某個連續區間 初始時都賦值為0 pos a i 表示值為a i 的數所在位置 當遇到情況 a i 1 或 a i 1 曾經 出現過時,mark pos a i 1 1 或 ...

hdu 4638 樹狀陣列

思路 將查詢區間按右節點的公升序排列,然後插入第i個數的時候,若nun i 1已經插入,那麼就update pre num i 1 1 pre表示的是該數的位置。同樣若 num i 1存在就update pre num i 1 1 因為他麼與num i 屬於一組,故只需乙個存在就行。當查詢的右邊界r...

hdu4638 Group(樹狀陣列)

題目大意 給乙個1 n的排列,然後詢問 x,y 區間中有多少個連續的段。如給乙個3 1 2 5 4,查詢是2 4,那麼就是問1 2 5中有多少個連續的串,一共有兩個串,1 2為乙個串,5為乙個串 若查詢是2 5,則問的是1 2 5 4中有多少個連續的串,一共有兩個串,1 2為乙個串,4 5 為乙個串...