d - hdu6703
題意:給乙個長度為n且互不相同的陣列。有m個操作,操作1是給a[pos]加上1000000,操作2是查詢在1-r沒有出現過同時大於k的值,並使其最小。
一種做法就是權值線段樹,每個節點維護該權值的下標,那麼原題就轉化為查詢[k,n]範圍內大於r的值,位置盡量靠左,即可使答案最小。
#include #define int long long
using namespace std;
const int n = 2e5 + 10;
struct segtree
void up(int k)
void build(int k, int l, int r, vector&b)
int m = (l + r) >> 1;
build(k<<1, l, m, b);
build(k<<1|1, m + 1, r, b);
up(k);
} void upd(int k, int l, int r, int p, int v)
int m = (l + r) >> 1;
if (p <= m) upd(k<<1, l, m, p, v);
else upd(k<<1|1, m + 1, r, p, v);
up(k);
} void upd(int p, int v)
int qry(int k, int l, int r, int p, int v)
int m = (l + r) >> 1, res = 0;
if (p <= m && t[k<<1] > v) else res = qry(k<<1|1, m + 1, r, p, v);
return res;
} int qry(int p, int v)
};signed main()
segtree seg(n, b);
int la = 0;
while (m--) else
} }return 0;
}
e - codeforces 1418g
題意:給乙個長度為n的陣列,問你有多少個這樣的區間,使得區間中每個數字恰好出現3次
參考部落格: blog.csdn.net/qq_45458915/article/details/108681107
#include #define ll long long
using namespace std;
const int n = 2e5 + 10;
struct segtree ;
int n;
vectort;
segtree(int n): n(n), t(n<<2) {}
void up(int k, int l, int r)
void upd(int k, int l, int r, int ql, int qr, int v)
int m = (l + r) >> 1;
if (ql <= m) upd(k<<1, l, m, ql, qr, v);
if (qr > m) upd(k<<1|1, m + 1, r, ql, qr, v);
up(k, l, r);
} void upd(int l, int r, int v)
};signed main()
cout << ans << '\n';
return 0;
}
10 25演算法訓練 裸線段樹
題目大意 對n 1 n 50000 個數進行連續進行m 1 m 200000 次詢問 問1 n之間任意連續區間最大值和最小值之差。之前學過線段樹,學的是模版題,求解的問題是在一段區間內任意加減,然後再詢問任意一段之區間的和。這次的問題和之前學的模版題相同之處是 查詢的是一段連續區間的資訊。所以之後的...
演算法訓練 操作格仔 線段樹
問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m。接下來一行n個整數表示n個格仔的初始權值。接下來m行,每行3個整數p...
高手訓練 線段樹 棧的維護
time limit 20 sec memory limit 512 mb 從前有個棧,一開始是空的。你寫下了 m 個操作,每個操作形如 k v 若 k 0,代表往棧頂加入乙個數 v 若 k 1,則代表從棧頂彈出 v 個數,如果棧中的元素少於 v 個,則全部彈出。接著你又進行了 q 次修改,每次你會...