zoukankan      html  css  js  c++  java
  • P6604 [HNOI2016]序列 加强版

    *I. P6604 [HNOI2016]序列 加强版

    摘自学习笔记 简单树论 笛卡尔树部分例题 I.

    P6503 比较类似。我们设 (f_i) 表示全局以 (i) 结尾的子区间的最小值之和,令 (p_i) 为下标在 (i) 之前第一个比 (a_i) 小的位置,显然有 (f_i=f_{p_i}+(i-p_i)a_i):因为 (a_i)(p_i) 以及 (p_i) 以前的最小值没有影响(即 ([1,p_i])([1,i])([2,p_i])([2,i]cdots) ([p_i,p_i])([p_i,i]) 的最小值相同),所以可以直接由 (f_{p_i}) 转移得来。而根据 (p_i) 的定义,后面 (i-p_i) 个子序列(即 ([p_i+1,i],[p_i+2,i]cdots,[i,i]))的最小值为 (a_i)

    注意到 (p_i) 实际相当于 (i) 在笛卡尔树上第一个向左走的父亲,求 (p_i) 的过程十分类似构建笛卡尔树:笛卡尔树上每个节点的祖先由左右两个单调栈构成

    考虑对一个区间求答案:求出区间最小值的位置 (p),那么左端在 (p) 左边,右端在 (p) 右边的子区间最小值为 (a_p),故答案加上 (a_p imes (p-l+1) imes (r-p+1))。此外,我们还需求出 ([l,p))((p,r]) 的答案:考虑 ((p,r]) 每个位置对答案的贡献都是 (f_r-f_p),因为 ([i,p])([i,r] (1leq ileq p)) 的最小值相同。前缀和优化可以做到 (mathcal{O}(1)) 回答每个询问。对于 ([l,p)) 同理,我们只需预处理出 (g_i) 表示全局以 (i) 开头的子区间的最小值之和并类似处理即可。

    复杂度瓶颈在于区间 RMQ,时间复杂度 (mathcal{O}(nlog n+q))

    const int N = 1e5 + 5;
    const int K = 17;
    
    namespace gen {
    	ull s, a, b, c, las = 0;
    	ull rand() {return s ^= (a + b * las) % c;}
    }
    
    int n, q, type, stc[N], *top = stc, a[N], lg[N], pre[N], suf[N];
    ll mi[K][N], fp[N], gp[N], fs[N], gs[N]; ull res;
    int cmp(int x, int y) {return a[x] < a[y] ? x : y;}
    int RMQ(int l, int r) {int d = lg[r - l + 1]; return cmp(mi[d][l], mi[d][r - (1 << d) + 1]);}
    
    int main(){
    	cin >> n >> q >> type;
    	for(int i = 1; i <= n; i++) a[i] = read(), mi[0][i] = i;
    	for(int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
    	for(int i = 1; i <= lg[n]; i++)
    		for(int j = 1; j + (1 << i) - 1 <= n; j++)
    			mi[i][j] = cmp(mi[i - 1][j], mi[i - 1][j + (1 << i - 1)]);
    	for(int i = 1; i <= n; i++) { 
    		while(*top && a[*top] >= a[i]) suf[*top--] = i; // 可以类比求笛卡尔树的过程: ls[i] = *top, 因此 suf[*top] = i;
    		pre[i] = *top, *++top = i; // 同理, rs[*top] = i, 所以 pre[i] = *top: 笛卡尔树上每个节点的祖先是由两个单调栈构成的!
    	}
    	for(int i = 1; i <= n; i++)
    		fp[i] = fp[pre[i]] + 1ll * a[i] * (i - pre[i]), gp[i] = gp[i - 1] + fp[i];
    	for(int i = n; i; i--)
    		fs[i] = fs[suf[i]] + 1ll * a[i] * (suf[i] - i), gs[i] = gs[i + 1] + fs[i];
    	if(type) gen :: s = read(), gen :: a = read(), gen :: b = read(), gen :: c = read();
    	for(int i = 1, l, r; i <= q; i++) {
    		if(type == 0) l = read(), r = read();
    		else {
    			l = gen :: rand() % n + 1;
    			r = gen :: rand() % n + 1;
    			if(l > r) swap(l, r);
    		}
    		ll p = RMQ(l, r), ans;
    		ans = a[p] * (r - p + 1) * (p - l + 1);
    		ans += gp[r] - gp[p] - fp[p] * (r - p);
    		ans += gs[l] - gs[p] - fs[p] * (p - l);
    		res ^= gen :: las = ans;
    	}
    	cout << res << endl;
        return flush(), 0;
    }
    
  • 相关阅读:
    图数据库的选择与对比(Neo4j)
    pip install ahocorasick报错以及Requirement already satisfied问题
    从知识图谱到认知图谱: 历史、发展与展望
    kafka(一)—— kafka安装简单使用
    python管理docker
    Javaweb前后端分离项目docker部署
    django + uwsgi + nginx部署(前后端不分离)
    坑(八)—— LayUI框架中append新的元素的问题
    docker(三)—— 避免一直输入sudo
    坑(七)—— 表单提交方式
  • 原文地址:https://www.cnblogs.com/alex-wei/p/P6604_sequence.html
Copyright © 2011-2022 走看看