• TJOI2014 Alice and Bob


    题目传送门

    神仙题

    Alice和Bob怎么整天在一起玩一些神仙游戏


    原序列为(x),输入的序列为(a)
    因为题目中是上升子序列下降子序列,所以原序列中相同的元素没有贡献,因此不妨设(x)(1)~(n)的一个排列
    (a_i)是以(x_i)为结尾的最长上升子序列的长度,所以对于所有的(a_k = a_i - 1),一定存在至少一个(k)使(x_k < x_i)
    如果要使Bob得分尽量高,可以贪心的使(a_i)较大的(x_i)尽量小,(a_i)相同的使(i)较大的(x_i)(即相对靠后的元素)尽量小

    考虑如何构造出符合上述条件的(x)
    对于(i),我们可以向离它最近的满足(a_k = a_i-1)(k)连一条边,这样可以构造出一棵树(以(0)为根)
    我们直接对这棵树求出它的dfs序数组(dfn),则(dfn)就是一个满足上述条件的序列
    因为前向星有一个特殊的性质:晚连上的边会被先遍历到。同时因为dfs先序遍历的特性(节点的dfs序小于它的子树中任意点的dfs序),求出来的(dfn)一定是满足上述所有条件的

    (0)是虚根,可以方便我们遍历,不过它会使(x_i)全都加(1),但这样显然不会对答案造成影响

    最后对(dfn)数组统计答案就可以了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    using namespace std;
    LL read() {
    	LL k = 0, f = 1; char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9')
    		k = k * 10 + c - 48, c = getchar();
    	return k * f;
    }
    struct zzz {
    	int t, nex;
    }e[100010 << 1]; int head[100010], tot;
    inline void add(int x, int y) {
    	e[++tot].t = y;
    	e[tot].nex = head[x];
    	head[x] = tot;
    }
    int a[100010], b[100010], dfn[100010], cnt, num;
    void dfs(int x, int fa) {
    	dfn[x] = ++cnt;
    	for(int i = head[x]; i; i = e[i].nex) {
    		if(e[i].t == fa) continue;
    		dfs(e[i].t, x);
    	}
    }
    int main() {
    	int n = read();
    	for(int i = 1; i <= n; ++i) {
    		int x = read();
    		add(a[x-1], i); add(i, a[x-1]); a[x] = i;
    	}
    	dfs(0, 0); LL ans = 0;
    	for(int i = n; i >= 1; --i) {
    		int pos = 0;
    		if(dfn[i] > b[num]) b[++num] = dfn[i], pos = num;
    		else pos = upper_bound(b+1, b+num+1, dfn[i]) - b;
    		b[pos] = min(b[pos], dfn[i]);
    		ans += (LL)pos;
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    Part0:安装Django
    计算机技术与科学系列笔记
    svg基础知识体系建立
    js如何判断字符串里面是否含有某个字符串
    js字符串如何倒序
    js判断值是否是数字
    HTML DOM 知识点整理(一)—— Document对象
    Git hub pull时候的错误 : The current branch is not configured for pull No value for key branch.master.merge found in configuration
    Map的3种遍历[轉]
    如何刪除GitHub中的repository
  • 原文地址:https://www.cnblogs.com/morslin/p/11855938.html
Copyright © 2020-2023  润新知