這道題想了很久 沒有想出來思路 後面上網找了題解 利用區間左端點連續 和右端點連續 處理了區間的連續
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...