JZOJ 6801. NOIP2020.9.19模擬patrick
阿新 • • 發佈:2020-09-19
題目大意
動態維護數列中大於等於某個數的極長連續段的個數。
思路
我們考慮每段的開頭,記為 \(i\),高度為 \(a_i\)
那麼此時水淹的高度必然滿足 \(a_{i-1} < x \leq a_i\)
這樣的 \(x\) 在此處會給答案貢獻加一
那麼我們考慮所有的這種位置,開一棵權值線段樹,對於這些 \(x\) 的位置都加 \(1\)
詢問時就單點查詢 \(x\) 線上段樹種的值就行了
修改時注意它原來的貢獻,包括它與前面的數和它與後面的數
這些減去,修改後在加上新的貢獻
然後,就沒有然後了······
\(Code\)
#include<cstdio> #define ls (k << 1) #define rs (ls | 1) using namespace std; const int N = 5e5; int n , m , a[N + 5] , last; struct seg{ int sum , tag; }t[4 * N + 5]; void pushdown(int k , int l , int r) { if (!t[k].tag) return; int m = (l + r) >> 1; t[ls].sum += (m - l + 1) * t[k].tag , t[ls].tag += t[k].tag; t[rs].sum += (r - m) * t[k].tag , t[rs].tag += t[k].tag; t[k].tag = 0; } void pushup(int k){t[k].sum = t[ls].sum + t[rs].sum;} void update(int l , int r , int k , int x , int y , int v) { if (x <= l && r <= y) { t[k].sum += (r - l + 1) * v; t[k].tag += v; return; } pushdown(k , l , r); int mid = (l + r) >> 1; if (x <= mid) update(l , mid , ls , x , y , v); if (y > mid) update(mid + 1 , r , rs , x , y , v); pushup(k); } int query(int l , int r , int k , int x) { if (l == r && l == x) return t[k].sum; pushdown(k , l , r); int mid = (l + r) >> 1; if (x <= mid) return query(l , mid , ls , x); else return query(mid + 1 , r , rs , x); } int main() { freopen("patrick.in" , "r" , stdin); freopen("patrick.out" , "w" , stdout); scanf("%d%d" , &n , &m); for(register int i = 1; i <= n; i++) { scanf("%d" , a + i); if (a[i] > N) a[i] = N; if (a[i] > a[i - 1]) update(1 , N , 1 , a[i - 1] + 1 , a[i] , 1); } char opt[5]; int x , y; for(register int i = 1; i <= m; i++) { scanf("%s" , opt); if (opt[0] == 'Q') { scanf("%d" , &x) , x ^= last; last = query(1 , N , 1 , x); printf("%d\n" , last); } else { scanf("%d%d" , &x , &y) , x ^= last , y ^= last; if (a[x] > a[x - 1]) update(1 , N , 1 , a[x - 1] + 1 , a[x] , -1); if (a[x + 1] > a[x]) update(1 , N , 1 , a[x] + 1 , a[x + 1] , -1); a[x] = y; if (a[x] > a[x - 1]) update(1 , N , 1 , a[x - 1] + 1 , a[x] , 1); if (a[x + 1] > a[x]) update(1 , N , 1 , a[x] + 1 , a[x + 1] , 1); } } }