• 【CSP模拟赛】God knows (李超线段树)


    题面

    在这里插入图片描述

    CODE

    稍微分析一下,发现把(i,pi)(i,p_i)看做二维数点,就是求极长上升子序列的权值最小值。

    直接李超线段树

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 200005;
    const int INF = 0x3f3f3f3f;
    int n, v, mxr, p[MAXN];
    int mx[MAXN<<2], vl[MAXN<<2], val[MAXN<<2];
    int cal(int i, int l, int r, int R) {
    	if(l == r) return mx[i] > R ? val[i] : INF;
    	int mid = (l + r) >> 1;
    	if(mx[i<<1|1] >= R) return min(vl[i], cal(i<<1|1, mid+1, r, R));
    	else return cal(i<<1, l, mid, R);
    }
    void insert(int i, int l, int r, int x, int pos, int V) {
    	if(l == r) { mx[i] = pos; val[i] = V; return; }
    	int mid = (l + r) >> 1;
    	if(x <= mid) insert(i<<1, l, mid, x, pos, V);
    	else insert(i<<1|1, mid+1, r, x, pos, V);
    	mx[i] = max(mx[i<<1], mx[i<<1|1]);
    	vl[i] = cal(i<<1, l, mid, mx[i<<1|1]);
    }
    void query(int i, int l, int r, int x) {
    	if(r <= x) { v = min(v, cal(i, l, r, mxr)); mxr = max(mxr, mx[i]); return; }
    	int mid = (l + r) >> 1;
    	if(x > mid) query(i<<1|1, mid+1, r, x);
    	query(i<<1, l, mid, x);
    }
    int main () {
    	scanf("%d", &n);
    	for(int i = 1; i <= n; ++i) scanf("%d", &p[i]);
    	memset(vl, 0x3f, sizeof vl);
    	for(int i = 1, c; i <= n; ++i) {
    		scanf("%d", &c);
    		v = INF, mxr = 0, query(1, 1, n, p[i]);
    		insert(1, 1, n, p[i], i, (v == INF ? 0 : v) + c);
    	}
    	v = INF, mxr = 0, query(1, 1, n, n);
    	printf("%d
    ", v);
    }
    
  • 相关阅读:
    C/C++ 链接汇总
    C# 网页操作
    Win10屏幕开始菜单图标丢失修复方案无意中发现的...
    AI 人工智能
    GIT 命令
    Layui / WEB UI
    PHP DES解密 对应Java SHA1PRNG方式加密
    视频参数介绍及关系《转》
    分布式时系统/服务 数据一致性方案
    JS埋点 小结
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039179.html
Copyright © 2020-2023  润新知