THUWC2018题目大意

Day1

T1

T1是一个很水很水的题,然而me没有看出来,于是各种分类讨论写了一百多行,貌似是少考虑了什么情况,那两个分最多的点始终是WA(这两个点值65分)…哎= =

题意大概是这样的:
现在有N个饼干,M个果干,每个饼干或果干都有各自的【妙值】。【妙值】是一个很特殊的属性,只有在连续吃同一类食品(连续吃饼干或者果干)的时候才会感受到它的【妙】,从而获得【妙值】。
现在,你可以任意安排吃东西的顺序,来尽可能的获得【妙值】。但是你不能在同一时间吃多个食物,并且如果上一个吃的种类与当前的不一样,则无法获得当前的【妙值】(假设吃的顺序是:1号饼干,2号饼干,3号饼干,1号果干,2号果干,那么只能获得2号饼干,3号饼干,2号果干的【妙值】)
请求出最多可以获得的【妙值】。
多组数据,总食物数量不超过200W

解法:理性思考一下发现,两类食物没有计入贡献的点最多相差一,直接sort一遍枚举即可

T2

题意大概是这样的:
有一棵树,每个节点各自有一个标号,还有一个信仰。现在需要从树中选出符合以下条件的联通块(要求块内任意两点都存在一条块内的路径):联通块内信仰个数不能超过2。
请求出所有符合条件的联通块个数,对大质数取模
数据结构常识范围

解法:
发现这个信仰个数不能超过2,这是一个很强的限制,于是考虑从这里入手
解法为树形DP,定义dp[u][c]表示,当前联通块最顶端节点为u,另一种颜色为c的方案数。
转移比较简单,dp[u][ color[v] ] <<累乘<< (dp[v][ color[v] ]+dp[v][ color[u] ]),每转移完一个就计入答案,然后就可以得到10分
观察到这个第二维,有很多其实是废的(如果没有颜色为c的节点与u相邻,那么dp[u][c]肯定是0),于是对于每个点,用一个map或者是哈希表存一下有效状态,转移的时候也只枚举有效状态,即可把复杂度缩减到 Nlog2N N l o g 2 N 级别

T3

T3的暴力比较好写,但是可惜me没有想出正解。最后也就只拿到了暴力分…
题意大概是这样的:
A表示一个字符串,定义符号 Ai A i ,表示A串第i个字符,定义符号 Ai...j A i . . . j 表示 Ai A i Aj A j 这一段所构成的子串。
定义字符串加法: A1...i+Ai+1...j=A1...j A 1... i + A i + 1... j = A 1... j
给出一个字符串 A A 。进行多组询问,每组询问给出一个字符串B,求出令A1...i+B+Ai+1...|A|字典序最小的i,并输出最靠前的那一个。
数据结构常识范围

解法:
暴力算法没什么好说的,最基础的暴力匹配,以及二分哈希匹配(二分到哈希最后一个相同的位置,那么这个位置的后一个位置就是第一个不同的字符,直接比较即可)。复杂度一个 N3 N 3 一个 N2log2N N 2 l o g 2 N

这个题目有一个部分分,所有询问串的长度都是1,对于这个特别的部分分,我们可以深入研究一下。可以发现询问串只有一个字符的时候,插入位置一定是在「找到第一个比插入字符大的位置pos,从pos往前第一个小于插入字符的位置pos2,那么插入位置就是pos2这个字符的后面」,正确性感性理解一下。

(后面记不太清了,可能会口胡)然后由这个算法,我们可以推广到一般情况。我们考虑一下在加入这个B串之后,这个新串与原串第一个不同的位置,显然我们要这个不同的字符尽量小,且位置尽量靠前。那么这个相同的前缀部分,有三种情况: A1...i+B+Ai+1...j A 1... i + B + A i + 1... j ,或者是 A1...i+B1...j A 1... i + B 1... j ,或者是 A1...i A 1... i 。对于第二种情况,可以发现B的一个前缀和A的某一个子串相同,那么我们一定可以将B的位置往后移动,然后可以归纳成第一种情况。于是我们只需要枚举,是A的哪一个字符可以做到不同,不同的最小字符可以是什么来快速得出答案。这里好像要建出一个后缀自动机,但是me这里就完全没听懂了…

Day2

T1

现在有一条公路途经了N个城市,按顺序标号1到N。每个城市之间隔着一定的距离,每个城市还有一个油价供路过的车辆加油。由于一些特殊的原因,车只能沿着1号到N号的方向行驶,并且所有车都有一个相同的油箱容量V。现在有一些旅行者路过此条公路,他们想知道各自行程的最小花费。对于每个询问,会给出 起始城市S和终止城市T,以及初始油量v,请你计算最小的花费。
城市数和询问都是5e5级别,油量上限1e18

解法:很容易发现一个贪心策略,假设当前城市为u,第一个油费更低的城市为v,如果可以从u一次到达v,那么就刚好加那么多油去v;不然就在u加满,然后在可达区间内选择一个油价最低的然后开过去(如果能够直接开到终点就不加满)。这里每次到达的点都是需要加油的(对于第二种情况,如果可以u->v->w【u->v通过第二种方法,v->w通过第一种方法】且不在v加油,那么w的油价应该比v还低,因此u会直接到w。而如果u->v->T都通过第二种方法且在v不加油,最后到了T还剩余的话,明显u可以直接到T,于是在u就会不加满)
然后发现,对于每个点,它的最优决策都是固定的,以此可以建出一棵树,对于每次询问跳倍增,倍增的时候累计贡献。从第一个需要加油的点开始倍增,倍增到 到达终点之前的最后一个点,然后走过去即可。

T2

有N种颜色的小球,每种有a[i]个,现在询问合法排列的方案数。对大质数取模
不合法排列是指:对于任意一个非空前缀或者非空后缀,如果N种颜色的小球出现了相同的次数,那么就不合法。(比如112122111111不合法,因为前缀112122中,两种颜色都出现了3次)
颜色数最多100种,每种颜色最多有200000个小球

解法:
首先考虑只有两种颜色的情况,我们把选择排列的过程看作是 在二位平面上从(0,0)走到(a[1],a[2])的过程,向左走相当于选颜色1,向上走相当于选颜色2,对于限制,可以看作是不能路过(1,1)、(2,2)…以及(a[1]-1,a[2]-1),(a[1]-2,a[2]-2)这样的一些点,然后统计方案数。DP是显然的。
那么对于多种颜色,也可以拓展到多维度上的方案数,不过这样的话复杂度就是 a[i] ∏ a [ i ] 的,明显会GG。

于是考虑补集转化,用总方案数减去不合法的方案数。总方案数很好求,就是总排列数除以颜色内排列数。对于不合法方案,我们在其经过的第一个非法点统计它,这里需要用到容斥。假设这个第一个经过的点是一个n维向量 u(x1,x2...xn) u ( x 1 , x 2 . . . x n ) ,从这个点走下去的总方案数计算方式和总方案数一样。第一个非法点是该点的走法的方案数,记作 F(u) F ( u ) ,从原点到点u的方案数记作 tot(u) t o t ( u ) ,则 F(u)=tot(u)F(ui)C(i) F ( u ) = t o t ( u ) − ∑ F ( u − i ) C ( i ) ,其中 C(i) C ( i ) 是广义的组合数,表示在N个维度上都偏移i的方案数。然后就只需要预处理出C数组,然后大力容斥一波即可。发现这个式子展开是多项式的形式,于是用上FFT优化即可。而C数组的处理貌似需要用到多项式运算(求逆,求和),这里me没有听懂…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值