把原陣列變為差分陣列,然後剩下的就十分顯然了
區間查詢用線段樹維護
修改操作就是區間加法和兩個單點修改
乙個等差數列實際上就是 開頭乙個數字+數值相等的一段
唯一的難點在於討論這個開頭的數字的去向
所以我們可以先不把左右兩端點列入考慮物件,然後在合併時再討論去向,綜上需要維護的東西有:
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...