bzoj 1558 JSOI2009 等差數列

2022-05-11 01:36:51 字數 1263 閱讀 2188

把原陣列變為差分陣列,然後剩下的就十分顯然了

區間查詢用線段樹維護

修改操作就是區間加法和兩個單點修改

乙個等差數列實際上就是 開頭乙個數字+數值相等的一段

唯一的難點在於討論這個開頭的數字的去向

所以我們可以先不把左右兩端點列入考慮物件,然後在合併時再討論去向,綜上需要維護的東西有:

1.區間的左右兩個端點都不列入考慮的等差數列數量

2.區間的左端點列入考慮

3.區間的右段點列入考慮

4.區間的左右端點都列入考慮

\(4\) 就是我們要求的,每一種情況的轉移都是類似的,轉移我們可以分三種情況討論:

1.左邊的右端點和右邊的左端點本身作為了等差數列的開頭,左邊的和右邊的等差數列直接合併,如果相鄰元素相等,則合為乙個等差數列

2.左邊的右端點自成乙個等差數列

3.右邊的左端點自成乙個等差數列

#include#define ls (o<<1)

#define rs (o<<1|1)

using namespace std;

const int n=1e5+10;

int n,q,a[n],w[n],la[n*4];

struct subt[n*4];

inline sub upd(sub a,sub b)

inline void build(int l,int r,int o)

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

build(l,mid,ls);build(mid+1,r,rs);

t[o]=upd(t[ls],t[rs]);

}inline void pushdown(int o)

inline sub qry(int l,int r,int o,int sa,int se)

inline void modify(int l,int r,int o,int sa,int se,int z)

pushdown(o);

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

if(se<=mid)modify(l,mid,ls,sa,se,z);

else if(sa>mid)modify(mid+1,r,rs,sa,se,z);

else modify(l,mid,ls,sa,mid,z),modify(mid+1,r,rs,mid+1,se,z);

t[o]=upd(t[ls],t[rs]);

}int main()

} return 0;

}

BZOJ1558 JSOI2009 等差數列

傳送門等差數列的題麼,先差分一下,然後就變成了乙個數列上,求 l,r 區間內連續相同的段數了。很相似的是 sdoi2011 染色這道題,但是由於我們這個線段樹存的是差分後的陣列,所以需要考慮乙個數是否作為乙個分段的頭和尾造成的影響。這個也是可以使用線段樹快速維護的。include using nam...

小店購物 JSOI2008 BZOJ 2260

grant是乙個個體戶老闆,他經營的小店因為其豐富的優惠方案深受附近居民的青睞,生意紅火。小店的優惠方案十分簡單有趣。grant規定 在一次消費過程中,如果您在本店購買了精製油的話,您購買香皂時就可以享受2.00元 塊的 如果您在本店購買了香皂的話,您購買可樂時就可以享受1.50元 聽的 諸如此類的...

BZOJ 4327 JSOI2012 玄武密碼

字尾自動機裸題。藉著這道裸題總結一下字尾自動機的查詢問題。1.查字首 查詢時不跳parent,遇到空節點就跳出。2.查子串 查詢時跳parent,記錄最大ans.3.查次數 lct維護right陣列 4.查不同的串的數目 在建樹時維護,乙個點對答案的貢獻為this max len this pare...