背景:
聰聰的性取向有問題。
題目描述:
聰聰遇到了乙個難題:
給出乙個序列a1…an,完成以下操作:
1 x 詢問從x向左數第乙個2 x 詢問從x向左數第乙個》ax的數;
3 x 詢問從x向右數第乙個4 x 詢問從x向右數第乙個》ax的數;
5 x y 交換ax與ay;
6 x y w 給ax…ay加上w;
7 x y w 給ax…ay減去w。
聰聰急切的想知道答案,因為他完成任務後就可以迎娶高富帥,出任ceo,走上人生巔峰,成為人生贏家!
請你幫幫他。
第一行 n,m。
第二行 a1…an。
第三行到m+2行為以上七個操作。
對於每個op>=1且op<=4輸出一行表示答案,無解輸出-1。
5 58 2 0 0 9
1 25 1 3
7 1 3 1
4 21 1-17
-110% n,m<=10000
40% n,m<=100000
100% n,m<=1000000
對於所有輸入的數保證在[0,10^9]範圍內
注:聰聰,出題人和高富帥都是往屆大佬
要求乙個點最靠近它且大於(小於)的值,有兩種考慮方法,一是記錄所查節點的位置,從根往下搜,
以找右邊較大為例,在左子樹下標大於所查點的前提下,盡量往左子樹走,否則向右子樹。
就這麼幹找。。。
第二種方法,(我打的就是這種非主流。。)從葉子節點往上找,
同樣以右邊較大為例,
如果在左子樹,而右子樹有大於它的,去右子樹向下搜,否則爬向父親。
如果在右子樹,直接爬到父親(因為無法向下走了)
而在向下走時,同樣,盡量走左子樹,否則走右子樹。
向左走反之。
最重要的是本題涉及lazy操作,什麼時候要傳的計算好,我就不寫了。
#include#include#include#include#include#define ll long long#define n 1000000
using namespace std;
ll n,m,a[n+5],b[n+5];
struct node
t[4*n+5];
ll read()
while(x>='0'&&x<='9')
return sum*f;
}inline void pushup(ll x)
inline void pushdown(ll x)
inline void build(ll l,ll r,ll x)
ll mid=(l+r)/2;
build(l,mid,x*2);
build(mid+1,r,x*2+1);
pushup(x);
}inline void pllus(ll l,ll r,ll k,ll x)
if(t[x].lazy)pushdown(x);
ll mid=(t[x].l+t[x].r)/2;
if(l<=mid) pllus(l,r,k,x*2);
if(r>mid) pllus(l,r,k,x*2+1);
if(t[x].l!=t[x].r)
pushup(x);
}void wohh(ll x)
inline void change(ll x,ll y)
inline ll min_ldown(ll k,ll x)
inline ll max_rup(ll k,ll x)
else
return max_rup(k,x/2);
}inline ll max_ldown(ll k,ll x)
inline ll max_lup(ll k,ll x)
else
return max_lup(k,x/2);
}int yjn()
}}int qty=yjn();
int main()
樹分治 BZOJ 2152 聰聰可可
考慮經過根的路徑,不經過根的路徑由分治得出。記子樹中的所有點到根的路徑長度對3取模以後為0的個數為a,為1的個數為b,為2的個數為c。組合數學容易算出路徑條數為a a b c 2。然後計算概率即可。include include include include include include inc...
POI2015 Kinoman(思維,線段樹)
這是一道不錯的題,不過我並沒有思考充分就實在忍不住看了題解,有點遺憾 記pre i 表示原序列i位置的數上一次出現的位置 每加入乙個數,我們發現pre i 1 i作為左端點的答案就增加了w,1 pre i 減少了w 我們可以列舉右端點,每加入乙個數進行區間加 減操作,不過我們發現,雖然從理論上來講的...
FJOI2015 火星商店問題 線段樹分治
這道題的每個詢問都有兩個區間,乙個是時間區間,乙個是商店編號區間。每個購買也是和時間商店編號有關。如何讓這兩個引數聯絡起來,就需要用到線段樹表示時間區間。線段樹可以把時間區間分細。對於每乙個詢問,它都有乙個時間區間 cn t1 d 1,c nt1 cnt 1 d 1,cnt 1 cnt1 d 1 c...