POI2015 Kinoman(思維,線段樹)

2021-09-10 08:53:03 字數 1156 閱讀 2495

這是一道不錯的題,不過我並沒有思考充分就實在忍不住看了題解,有點遺憾

記pre[i]表示原序列i位置的數上一次出現的位置

每加入乙個數,我們發現pre[i+1]~i作為左端點的答案就增加了w,1~pre[i]減少了w

我們可以列舉右端點,每加入乙個數進行區間加/減操作,不過我們發現,雖然從理論上來講的確是1~pre[i]減少了w,不過如果每次都區間減,那會減出問題的。所以實際上,每次只需要對pre[pre[i]]+1~pre[i]減就行了。

至於答案,每加入新端點就查詢1~n的最大值即可

區間修改+最大=線段樹

#include#define ll long long

const int n=1000005;

using namespace std;

templateinline void read(t &x)

while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();

x*=f;

}int n,m,pre[n],f[n],base[n];

ll w[n];

struct tree

tree[4*n];

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

inline void pushdown(int now)

inline void modify(int now,int l,int r,ll x)

pushdown(now);

int m=(tree[now].l+tree[now].r)>>1;

if(l<=m) modify(now<<1,l,r,x);

if(r>m) modify(now<<1|1,l,r,x);

tree[now].maxv=max(tree[now<<1].maxv,tree[now<<1|1].maxv);

}inline ll query(int now,int l,int r)

int main()

build(1,1,n);

for(int i=1;i<=m;i++) read(w[i]);

ll ans=0;

for(int i=1;i<=n;i++)

cout

}

POI2015 LOG(樹狀陣列)

今天考試考了這題,所以來貢獻 poi2015 log 的第一篇題解。略醜,調了快三個小時才調出來 ac 對於這種小清新資料結構題,所以我覺得樹狀陣列才是這道題的正確開啟方式。首先離散化,這樣才不會爆記憶體。開兩個樹狀陣列,第乙個樹狀陣列記錄離散化後 1 到 i 中數字出現的個數,第二個樹狀陣列離散化...

省選專練POI2015Kinoman

小目標 高考假以內,做完poi2015 和poi2014的一半 怎麼搞?實際套路也挺簡單的。你看 l,r。這是n n的演算法 一般來說1e6 怎麼搞是on 但是onlogn 卻必須得跑過 原因是一般來說解決是列舉乙個l 或者是中位數。但是必須得log 那麼毒瘤卡常數 你用乙個後向星記錄乙個 pre即...

TJOI2015 弦論(第k小子串)

題意 對於乙個給定的長度為n的字串,求出它的第k小子串。有引數t,t為0則表示不同位置的相同子串算作乙個,t為1則表示不同位置的相同子串算作多個。題解 首先,因為t的原因,字尾陣列較難實現,這裡不討論。使用字尾自動機 因為,這裡需要按字典序考慮子串,所以要使用trs指標。首先,計算出每個子串的貢獻 ...