zoukankan      html  css  js  c++  java
  • 模拟100 题解

    A. 组合

    将两个字符之间建边,

    问题转化为一笔画,也就是欧拉路问题。

    所以直接用dfs压栈的方法解决,注意正确使用当前弧优化。

    void dfs1(int x){
    	for(int i=head[x];i;){
    		if(vis[i>>1]){
    			head[x]=nxt[i];
    			i=nxt[i];
    			continue;
    		}
    		vis[i>>1]=1;
    		dfs1(to[i]);
    		stack[++top]=w[i];
    		i=head[x];//如果忽略这句话 复杂度仍为E^2
    	}
    }
    

    B. 统计

    实际上消失的逆序对只产生在进行排序的点之间。

    所以可以预处理出每个点与它后面的多少个点产生了逆序关系。

    对于一个点,问题是将它后面的且权值不大于它的点产生的逆序关系删去。

    似乎是一个二维点对问题,显然可以用链表维护然后就AC了。

    因为每个点只会删一次,所以用线段树维护区间最值,

    当递归到叶子节点或区间最值已经超过当前要求时$return$。

    因为删除次数是合法的,其复杂度为$O(nlogn)$

    C. 点亮

    因为数据保证随机,深度不会很大。

    注意到实际上并不关注每个点对之间的关系,

    当每层祖先中亮着的点与暗着的点的大小关系确定,每个点的点权是确定的。

    所以可以状压每层祖先的状态。预处理出每个点对于每个状态的点权。

    设$dp_{i,j,s}$表示点$i$的子树中有$j$个被点亮,祖先链的状态为$s$。

    之后可以直接作树上背包转移。

  • 相关阅读:
    学习笔记2-查看目录文件
    学习笔记1-基本信息及相关目录
    【图论】二分图最大匹配
    【图论】Dinic算法
    【图论】最小割
    【数据结构】左偏树
    【数学】欧拉定理
    【数据结构】ST表
    【数学】博弈模型
    【字符串】后缀数组
  • 原文地址:https://www.cnblogs.com/skyh/p/11796145.html
Copyright © 2011-2022 走看看