線段樹處理 poj2892 hdu1540

2021-07-24 02:43:09 字數 1327 閱讀 1723

這道題想了很久 沒有想出來思路 後面上網找了題解 利用區間左端點連續 和右端點連續 處理了區間的連續

sum陣列儲存連續村莊個數,lsum儲存區間內從左起連續個數,rsum儲存區間內從右起連續個數

#include #include #include #include using namespace std ;

#define inf 0xfffffff

#define lson l,m,rt<<1

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

const int maxn=55555;

int num[maxn<<1];

int sum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2];

//sum陣列儲存連續村莊個數,lsum儲存區間內從左起連續個數,rsum儲存區間內從右起連續個數

void pushup(int rt,int m)

void build(int l,int r,int rt)

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

build(lson);

build(rson);

pushup(rt,r-l+1);

}void update(int key,int add,int l,int r,int rt)

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

if(key<=m) update(key,add,lson);

else update(key,add,rson);

pushup(rt,r-l+1);

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

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

int ans=0;

int a=l+lsum[rt]-1;int b=r-rsum[rt]+1;

if(key>=l&&key<=a) ans=lsum[rt];

if(key>=b&&key<=r) ans=max(ans,rsum[rt]);

int c=m-rsum[rt<<1]+1;int d=m+lsum[rt<<1|1];

if(key>=c&&key<=d) ans=max(ans,rsum[rt<<1]+lsum[rt<<1|1]);

if(ans) return ans;

if(key<=m) return query(key,lson);

else return query(key,rson);

}int main()

else if(str[0]=='r')

else}}

return 0;

}

hdu 預處理 線段樹)

給n個數,m個詢問,問任意區間內與其它數互質的數有多少個 比如3個數1 2 4,詢問 1,3 那麼答案是1 千萬要記住,這樣的題目,如果你不轉變下,使勁往線段樹想 雖然轉變之後,也說要用到線段樹,但是維護的東西不同了 那麼會發現這樣的題目,區間與區間之間是無法傳遞資訊的,區間與區間是無法傳遞資訊的,...

poj 2828 線段樹插孔處理

給你乙個數列出現的先後順序num i 和對應數值 輸出最後排好序的對應數值,如 4 0 77 1 51 1 33 2 69第一步 77 第二部 77 51 第三步 77 33 51 第四部77 33 69 51 後面先出現的位置是固定的 所以從後往前處理。線段樹每個節點存當前區間還有多少個空位 in...

hdu 4288 線段樹 離線處理

hdu 4288 題意 給你類似乙個公升序的set結構 add就是加入乙個數 del就是刪除乙個數 sum就是把所有 5 3的位置的數求和 這題我們怎麼入手呢?以前做過一道類似的樹狀陣列開55個的題 這個題其實大同小異 就是對sum陣列表示 5的值我們開個sum 5 那麼你既然是公升序的 我每次ad...