需要3個標記,分別是左區間連續長度,右區間連續長度,中間區間的最大連續長度(最大可以通過更新回溯的過程中,pushup中更新)。
題目的難點是如何找合適的連續區間。
因為題目要求的是最左邊的符合題目要求的區間,所以找區間的時候要先看左區間的連續長度,其次是中間區間的連續長度(因為中間可能會有多個連續的區間,所以要遞迴下去找,順序一樣是從左開始找),最後是右區間的連續長度。
**量可能會很大,所以要細心,耐心一點。
還有需要注意的是輸出最好從樣例裡複製貼上。
#include #include #include #include #include #include using namespace std;
const int maxn = 1e5+10;
const int mod = 10007;
typedef long long ll;
int ds[maxn<<2], ns[maxn<<2], dsmid[maxn<<2], nsmid[maxn<<2], dsleft[maxn<<2], dsright[maxn<<2],
nsleft[maxn<<2], nsright[maxn<<2];
int l, r, op, ans, len;
void pushdown(int cur, int l, int r)
if(ds[cur] == 0)
if(ns[cur] == 1)
if(ds[cur] == 1)
}void pushup(int cur, int l, int r)
void updata(int cur, int l, int r) else if(op == 2) else
return;
}int mid = (r+l)>>1;
pushdown(cur, l, r);
if(l <= mid) updata(cur<<1, l, mid);
if(mid+1 <= r) updata(cur<<1|1, mid+1, r);
pushup(cur, l, r);
}void dsquery(int cur, int l, int r) else if(dsright[cur] >= len) ans = r-(dsright[cur])+1;
}void nsquery(int cur, int l, int r) else if(nsright[cur] >= len) ans = r-(nsright[cur])+1;
}int main(void)
} else if(!strcmp(ch, "ns")) else
}} else }}
return 0;
}
HDU 4553 約會安排 線段樹
題意 有個屌絲有t的空閒時間。每次有人與他約t的時間,他都會找到最靠前的一段符合要求的時間,稱為 最先適應演算法 1,如果 約他,他就會按 最先適應演算法 去找,找到就約否則不約。2,如果女神約他,他也會先按原先的方法去找,如果找不到,那他會忽略所有與 的約定而通過原來的方法去找跟女神約會的時間,找...
hdu4553約會安排 線段樹
ds qt 找一段最靠前的長度為qt的空間 ns qt 找一段最靠前的長度為qt的空間,如果沒找到可以將ds佔據的空間當做空閒空間,找一段最靠前的空間 study l r 清空l r的空間 用兩個線段樹,乙個處理ds的情況,乙個處理ns的情況 線段樹維護,ma l ma r ma 區間 l,r 的左...
hdu4553約會安排 線段樹
ds qt 找一段最靠前的長度為qt的空間 ns qt 找一段最靠前的長度為qt的空間。假設沒找到能夠將ds占領的空間當做空暇空間,找一段最靠前的空間 study l r 清空l r的空間 用兩個線段樹,乙個處理ds的情況。乙個處理ns的情況 線段樹維護,ma l ma r ma 區間 l,r 的左...