給出長為n(<=5e5)的序列,要求支援區間加、區間取min/max、區間求和、區間求min/max。這麼說起來,50w 雙log 真是信仰式複雜度。。我 好久好久以前 就想學這個科技… o(
nlog
2n) o(n
log2
n)
的segme
nttr
eebe
ats!se
gmen
ttre
ebea
ts
!區間取min/max時,對於被包含的區間,如果可以只更改min/max的值,那麼直接修改,否則暴力dfs下去。
其他操作不變。
聽說課件裡那個單log的證明有鍋?
照本宣科一發。
勢能函式定義為線段樹里最值異於其父節點最值的節點個數。
以區間對v取min為例。
終止節點只有
v>=ma
x v
>=ma
x和s
ec<
vx sec
<
v
x第一種的兄弟節點一定是被訪問過的非終止節點或第二種終止節點,所以這個我們不考慮。
第二種終止節點在取min後的max和父節點的max相等。
因此勢能函式減少
a a
,對複雜度的貢獻是al
ogn' role="presentation">alo
gnal
ogn。
區間加涉及lognl
og
n個節點,因此勢能函式最多增加ml
ogn mlo
gn
。 所以總複雜度是ml
og2nml
og2n
。
為什麼我跑得這麼慢!這麼慢!!
剛開始每個點比std慢了0.5s左右。。
在奇怪的地方卡了下常…函式能不呼叫就盡量不要呼叫,在外面判會比在裡面判快很多…
真是強行加長**(
#include
#define n 500005
#define mid (l+r>>1)
#define inf 0x3f3f3f3f
#define pu sum[k]=sum[k<<1]+sum[k<<1|1],upd(k,0),upd(k,1)
#define cmp(x,y) (d?xy))
#define p(x) ad[k]?add(k<<1|x,ad[k]):(void)0,fm[0][k<<1|x]fm[1][k]?mini(k<<1|x,fm[1][k],0):(void)0
#define pd p(0),p(1),ad[k]=0
using
namespace
std;
typedef
long
long ll;
int f,c,v;
inline
void rd(int &x)
ll sum[n<<2];
int n,m,ll,rr,len[n<<2],
fm[2][n<<2],fc[2][n<<2],se[2][n<<2],ad[n<<2];
inline
void add(int x,int y)
inline
void upd(int k,bool d)
void build(int k,int l,int r)
inline
void mini(int k,int s,bool d)
void mdf(int k,int l,int r,int d)
pd,mdf(k<<1,l,mid,d),mdf(k<<1|1,mid+1,r,d),pu;
}int qry(int k,int l,int r,bool d)
ll qsum(int k,int l,int r)
int op;
int main()
BZOJ4695 最假女選手
傳送門 題目大意 維護乙個序列,支援區間加,區間取 max,min 區間求和,區間求最大最小值。題解區間取 max,min 必然要用到神奇的吉老師線段樹,即維護區間最大值 最大值數量,次大值來剪枝。即,當取 min 介於最大值和次大值之間時進行修改,否則暴力遞迴子樹。區間取 max 同理。這道題還要...
BZOJ4695 最假女選手
區間最值操作和歷史最值問題 題目傳送門 吉司機線段樹板子大集合。所有資訊都封裝在乙個結構體裡會比開多個陣列快14秒。注意暴力 dfs 子樹時要 pushdown 時間複雜度 o nlog 2n 空間複雜度 o n 如下 include include using namespace std type...
bzoj4519 CQOI2016 不同的最小割
time limit 20 sec memory limit 512 mb submit 418 solved 254 submit status discuss 學過圖論的同學都知道最小割的概念 對於乙個圖,某個對圖中結點的劃分將圖中所有結點分成 兩個部分,如果結點s,t不在同乙個部分中,則稱這個...