火星補鍋 siano 神奇的線段樹

2022-02-02 00:35:07 字數 1401 閱讀 5152

本來以為很難打的,沒想到主幹一次就打對了,然而把輸入的b和d弄混了,這sb錯誤調了兩個小時。。。

神奇的線段樹。注意到有乙個性質,無論怎麼割草,生長速度快的一定不會比生長速度慢的矮。因此可以先排個序,然後就可以用線段樹維護了。

首先維護區間的sum,這個很顯然。

然後會發現乙個問題,每次割草時,不知道從**開始割。這時可以運用線段樹上二分的思想,維護乙個區間max,每次只要查詢區間中第乙個大於上限的位置即可。

還有區間賦值和區間加的標記,這個就是細節問題了。

**:

#include using namespace std;

typedef long long ll;

const int maxn=500000+10;

#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? eof : *p1++) : *p1++)

#define read() ( while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })

char buf[1 << 20], *p1, *p2;

int n,m;

ll sum[maxn];

ll b,d,last,ans;

int a[maxn];

struct segment_treetree[maxn<<2];

bool cmp(int x,int y)

void update(int rt,int l,int r,ll x)

void updateadd(int rt,int l,int r,ll x)

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

if(tree[rt].lazyadd)

}void mm(ll x)

int query(int rt,int l,int r,int s,int t,ll x)

ll querysum(int rt,int l,int r,int s,int t)

void pushup(int rt)

void modify(int rt,int l,int r,int s,int t,ll x)

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

pushdown(rt,l,r);

if(s<=mid) modify(rt<<1,l,mid,s,t,x);

if(t>mid) modify(rt<<1|1,mid+1,r,s,t,x);

pushup(rt);

}void solve()else ans=0;

printf("%lld\n",ans); }}

int main()

神奇線段樹QWQ

線段樹基於分治的思想會分治的思想,用於區間求值問題。比如說 求區間的最大值,最小值等等 給出乙個長隊為8的區間對他進行操作。先將他分成若干區間 如圖藍色為區間標號,紅色為區間 直到分成單個點並把所需要的資訊存到單點上。建樹 void build tree int k,int l,int r 如果l ...

FJOI2015 火星商店問題 線段樹分治

這道題的每個詢問都有兩個區間,乙個是時間區間,乙個是商店編號區間。每個購買也是和時間商店編號有關。如何讓這兩個引數聯絡起來,就需要用到線段樹表示時間區間。線段樹可以把時間區間分細。對於每乙個詢問,它都有乙個時間區間 cn t1 d 1,c nt1 cnt 1 d 1,cnt 1 cnt1 d 1 c...

模擬 神奇的樹

time limit 1000ms memory limit 65536k sdut有一顆神奇的蘋果樹。假如某天早上這樹上有x個蘋果,那麼這樹這一天會再結出x個蘋果來,也就是說到了晚上會有2 x個蘋果,到了深夜,會有專人人來摘蘋果,而摘蘋果的人總會使蘋果數剩下當前數量對m的餘數,也就是說假如當前數量...