zoukankan      html  css  js  c++  java
  • 2019.10.15模拟赛

    关于这次考试

    这次考试感觉下发文件高端大气上档次。每个题八个样例,提供详细的数据解析。并且提供了答案文件比较器以及对拍器。真的是很厉害了。虽然T3的std锅了

    T1 神在夏至降下了神谕

    题面

    参与这场演出的一共有 N+M 位战士,其中 N 个人是冬之军,M 个人是夏之军。
    冬之军的大将冬男拥有改变季节的力量。他每次可以任意选取恰好 K 名战士,然后把这 K 个人中所有的夏之军变成冬之军,所有的冬之军变成夏之军。
    冬男可以使用任意多次改变季节的力量,直到他将所有的人都变成了冬之军。
    如果冬男将所有的人都变成了冬之军,那么冬男就获得了胜利。
    我想要知道,对于给定的 N,M,K,冬男是否有可能获得胜利。

    这题样例太友善了直接告诉答案

    分情况讨论一下:
    (m = 0),直接取得胜利。
    (m\%k =0),一定可以直接把所有夏之军改为冬之军。
    (m + n {leq} k),无法转变夏之军。
    (m 是奇数, k 是偶数),无论如何转化,都会剩余奇数个夏之军。
    (k是奇数),无论m奇偶,一定可以修改m个夏之军。
    就这样切掉了这道题。

    inline bool sov() 
    {
        poread(n), poread(m), poread(k);
        if (m % k == 0)
            return 1;
        if (m != 0 && n + m <= k)
            return 0;
        if (m & 1 && !(k & 1))
            return 0;
        return 1;
    }
    

    T2 灰狼呼唤着同胞

    题面

    二十年前的混沌,一共有 n 块碎片。
    这 n 块碎片曾经两两之间都有联系,可是很多联系都在时间的洪流中消失了。
    现在,我只能确定其中 m 条联系的种类。 每条联系都是一条无向边,任意两块碎片之间至多有一条联系,没有联系会连接在同一块碎片的两端。
    联系有两种。一种是冲突,用 0 表示;另一种是吻合,用 1 表示。 虽然已经过去了二十年,但是联系的种类是不会变的。
    现在,我想要用这 m 条联系,去推断二十年前的 n(n-1)/2 条联系的种类。
    二十年前,对于任意三块互不相同的碎片,要么这三块碎片两两吻合,要么恰好有一对碎 片互相吻合。
    我想要知道,二十年前 n 块碎片两两之间的联系,可能有多少种。
    你只要输出方案数模 998244353 之后的结果。如果已经确定的 m 条联系不符合上述条件,请输出 0。

    咋做

    判断是否合法,使用边带权的并查集或者扩展域即可。详见lyd《算法竞赛进阶指南》。
    统计方案数:其实就是(2^{连通块个数 - 1})
    解释:这道题相当于二分图之间连边计算方案数。
    对于每一个联通快,我们都已知其中个点的相互情况。(位于左部节点或者右部节点)。
    而它与其他连通块的关系是未定的,我们可以将1号连通块的同一部的节点与二号连通块的某一部节点建立联系,这样的联系会有两种,之后我们则认为1,2两个连通块状态已知。
    于是对于每两个连通块,都可以建立这样的联系,一共会有cnt-1个联系,答案就是(2 ^ {cnt-1})
    图片解释:

    int find(int x)
    {
    	return fa[x] == x ? x : fa[x] = find(fa[x]);
    }
    inline void merge(const int &x, const int &y)
    {
    	register int X = find(x), Y = find(y);
    	if (X != Y)
    		fa[Y] = X;
    }
    inline int sov()
    {
    	poread(n), poread(m);
    	cerr << n << m << endl;
    	for (register int i = 1; i <= n * 2; ++i)
    		fa[i] = i;
    	for (register int i = 1, x, y, t; i <= m; ++i)
    	{
    		poread(x), poread(y), poread(t);
    		if (t == 1)
    		{
    			if (find(x + n) == find(y) || find(y + n) == find(x))
    			{
    				for(;i < m; ++i)
    					poread(x),poread(y),poread(t);
    				return 0;
    			}
    			merge(x, y);
    			merge(x + n, y + n);
    		}
    		else
    		{
    			if (find(x) == find(y) || find(x + n) == find(y + n))
    			{
    				for (; i < m; ++i)
    					poread(x), poread(y), poread(t);
    				return 0;
    			}
    			merge(x, y + n);
    			merge(x + n, y);
    		}
    	}
    	register int cnt = 0;
    	for (register int i = 1; i <= n; ++i)
    		cnt += (fa[i] == i);
    	cerr << cnt << endl;
    	return qpow(2, cnt - 1);
    }
    

    T3 两只怪物心心相印

    ps:这题竟然线段树优化建图,考场上见了就暴力分走人了。还有,std竟然锅了。

    题面

    【题目背景】 从前我是一位无名的旅人,旅途中我得到了某样东西:贤者之石。我因此得到悠久的时光 和漂泊的生命。1897 年冬天,我一时兴起舍弃了旅人的生活。 贤者之石创造出来的,是货真价实的黄金。我的名声传遍了整个国家。
    【题目描述】 炼金术的要素,是炼金树和贤者之石。
    炼金树是一棵含有 n 个节点的无根树,树上一共有 n-1 条石榴色的无向边。第 i 条无向边 长度为 Li。
    我一共会使用 m 次炼金术。
    每次使用炼金术时,我首先会把一块石榴色的贤者之石放在炼金树的某个节点 x1 上。然后, 我会将若干块蓝色的贤者之石放在炼金树的其它 K1 个节点上。保证一个节点不会同时放入两块 贤者之石。然后,我会使石榴色的贤者之石熔化。熔化后的贤者之石,只能沿着石榴色的边流 动,既不会与蓝色的贤者之石接触,也不会进入蓝色的贤者之石所处的节点内。凝固后,含有 石榴色的贤者之石的节点集合记为 S1。很显然,S1 是一个包含 x1 的连通块。记 S1 的大小为 |S1|。
    题目截图
    对于上图所示的炼金树,如果我把石榴色的贤者之石放在 5 号节点,把 4 块蓝色的贤者之 石分别放在 1、3、7、9 号节点,那么熔化后石榴色的贤者之石就会流到 2、5、6、8 号节点。 此时 S1={2,5,6,8},|S1|=4。
    然后,取出所有的贤者之石,选择 x2、K2 和新的 K2 个节点,用相同的方法,可以再次确 定一个节点集合 S2。记 S2 的大小为|S2|。你可以认为,确定 S1 的过程和确定 S2 的过程是互 不干扰的。
    最后,从 S1 中的每个节点分别向 S2 中的每个节点连一条长度为 W 的金色的有向边。注意, 在同一次炼金术中连接的金色边长度都相同。
    很显然,每次使用炼金术,都会增加|S1|*|S2|条有向边。
    由于贤者之石熔化后只能沿石榴色的边流动,因此每次炼金术是相互独立的。 有时 S1 里面只会包含 1 个节点 x,那么我可以不需要使用蓝色的贤者之石,直接将石榴色 的贤者之石放在 x 号节点即可确定 S1,此时令 K1=-1。当然,我也可以用上述方法确定 S2, 此时令 K2=-1。
    使用完 m 次炼金术后,我会在 1 号节点灌入液态的黄金。黄金既可以沿石榴色的边流动, 也可以沿金色的有向边流动。很显然,黄金流入 i 号节点的时间,就是 1 号节点到 i 号节点的 最短路。
    我想要知道,使用完 m 次炼金术后,黄金从 1 号节点流入每个节点的时间。
    简单来说,在一棵树上,每次由一部分点向另一部分点连接有向边,求最后根节点到所有节点的最短路长度

    考场骗得76分

    由于每次更新是由S1更新S2,类似SPFA的做法,挑选出S1中d[x]最小的点x_s1,并由x_s1更新S2中所有点的d[x]。更新之后,由于S2的更改会导致全图中的最短路更新,所以再跑一遍SPFA。时间复杂度(O(nm)),于是乎76分骗到手。

    但是

    这个算法是错误的
    在由x_s1更新d[x]后,并没有更新边权,于是乎下次更新x_s1之后,会按照更劣的边长更新d[x]以及全图最短路,导致答案错误。
    详情看图:

    不要说直接修改边权,因为如果在树上会有很多边根本没有建出来同样没有更新。
    数据太水过了不少分。。。

    正解

    线段树优化建图。
    先咕咕咕,学会了再来更新。

  • 相关阅读:
    FPGA+ADV7511实现HDMI显示
    【转载】ZYNQ Cache问题的解决方法
    FPGA控制RGMII接口PHY芯片基础
    【转载】linux 压缩和解压缩命令gz、tar、zip、bz2
    python中正则表达式与模式匹配
    【转载】数字IC设计流程及开发工具
    Linux基本操作——文件相关
    数字信号处理专题(3)——FFT运算初探
    C++基础——类继承中方法重载
    C++基础——类继承
  • 原文地址:https://www.cnblogs.com/Shiina-Rikka/p/11685186.html
Copyright © 2011-2022 走看看