zoukankan      html  css  js  c++  java
  • IOI2020只因训队作业胡做

    多半是废了QAQ

    要退役了,此帖以废 --20.02.09

    随缘更 --20.03.30


    w a r n i n g ! 意 识 流 警 告 !!1

    不想一个个发了,干脆直接发个合集得了qwq

    但感觉这辈子都做不完了(Qomega Q)

    CF516D

    写过题解了

    CF505E

    写过题解了*2

    CF555E

    首先对于一个边双,一定存在一种定向方案满足任意两点可达.那把边双缩点,原图就变成了一棵树,询问的两点路径可以拆成一段往上走的链和一段往下走的,那么就要使得若干链上的边都往上或都往下,搞两种差分数组统计一下,不合法当且仅当一条边在两种差分数组里都有值

    code

    CF704B

    JOISC邮戳拉力赛

    题解先咕着

    code

    CF704C

    将每个((x_i|x_j))看成是一条边((i,j)),那么就可以得到一堆链或者是环(有可能是自环),每个连通块显然是独立的,可以先求出每个连通块的状态,然后并到一个全局背包里去.那么对于每个链就链上dp出每个子树内异或和为(0/1)的方案,转移只要枚举自己这个点的取值,然后类似背包合并上一个点的dp值就行了;至于环上dp,因为是个环,那就断环为链,dp出链的异或和为(0/1)的方案,然后dp完链后考虑被断掉的那条边的贡献.具体实现可能需要(ygrave{i})点细节

    code

    CF521D

    显然三种操作之间应该先赋值,然后加,最后乘.然后对于一个数,赋值只需要取赋的值最大的一次操作,发现这样可以把赋值改为加操作.题目要求(prod x_i)最大,取个对数后可以变成要(sum log x_i)最大,乘法对于(log x_i)的贡献量是不会变的,而加法操作显然要先用大的再用小的,排序后可以用(log(x_isum_{j=1}^{i}b_j)-log(x_isum_{j=1}^{i-1}b_j))算第(i)个加法操作的贡献量.最后选出贡献最大的(k)个操作就是答案,输出注意三种操作之间的顺序

    code

    CF512D

    这题本质上还是个背包.注意到这个遍历过程相当于每次选一个度数为1的点删掉.如果一个连通块是树,那么遍历若干个点后一定会剩下一个子连通块,那就可以换根dp出在树上挖掉若干个点的方案数;如果连通块上有若干个环,因为环上的点是一定不能删的,那么只有挂在环上点外面的子树,并且满足子树内有度数为1的点的部分可以删去(参考样例3解释的那个大连通块,除了环上4个点都可以挖掉),那么就对这些部分分开树型背包(这里不需要换根,因为根就是对应在环上的点).然后把一个dp过程中,以及合并答案过程中要乘上组合数(因为两个没有子树关系的部分是相互独立的,他们的选点顺序可以交错开来)

    code

    CF575A

    显然要矩乘.这里的话大概预处理一个倍增的矩阵,表示在第(imod n)项,往后转移(2^k)步的转移矩阵,每次就倍增转移到下一个断点,然后断点处特殊转移.复杂度为(O(8nlogk+8mlogk)),其中(8)为矩乘复杂度

    code

    CF547D

    CF704D弱化版

    我们对每个横纵坐标建点,然后一个点((x,y))就给横坐标(x)和纵坐标(y)连一条无向边,然后给边定向,如果是(x o y)就是红色,否则就是蓝色.因为某个坐标上红蓝点数之差的绝对值要(le 1),所以定向后要使得所有点入度和出度的差的绝对值要(le 1).如果是强制入度等于出度,这实际上是一个欧拉回路,所以我们把所有度数为奇数的点两两配对连边,那么就可以跑欧拉回路了,定向之后再把后面加进来的边删掉,这样所有点入度出度都会满足条件

    code

    CF536D

    我们以(s)(t)为起点,跑其他点到起点的最短路,然后就能得到对于这两个点,按照最短路长度排序后的序列,现在问题变成有两个序列,每次操作的一方要在之前选择前缀的基础上接着选择一段,还要满足这新的一段存在之前没有被两个人选到过的点,然后每个人用最优策略博弈.那就可以设(f_{i,j})表示这次是先手操作,操作前两个序列被选了前缀(i)(j)的最大权值,(g_{i,j})表示的是后手,转移直接枚举这一次选到哪一个位置,然后用后面一段还没被选的权值总和减去对应的(f/g)更新.注意到转移的时候只有一维会变,所以可以对每一维记录后缀最小值,即可做到(O(n^2))

    code

    CF576D

    最短路?(nle 150)?考虑矩乘.用行向量维护某个时刻是否可以到达某个点,然后本质不同的转移矩阵段只有(O(m))个,所以在每一段先转移(n)步,看能不能到点(n),然后剩下部分可以快速幂转移.精细实现可以做到(O(n^3mlog|V|)).注意到矩阵是(01)矩阵,所以套个(bitset)可以得到(frac{1}{omega})的常数优化

    code

    CF506E

    考虑从两边往中间填,设(f_{i,l,r})表示开头结尾已经填了(i)次,然后整个串还有([l,r])没被填进去.每次填字符的时候,如果当前串左右两边能够填就尽量填.最后转移完如果最终长度为偶数答案就是(sum f_{frac{n+m}{2},i+1,i}),如果是奇数就还要加上(f_{lfloorfrac{n+m}{2} floor,i,i})(第(i)个字符在整个串最中间).这样在套上一个矩乘,就可以做到6方(log)

    考虑优化,首先可以发现转移只有 三加一 种

    • 填的字符和(s_l,s_r)不同
    • 填的字符和(s_l,s_r)之中一个相同
    • 填的字符和(s_l,s_r)都相同
    • 可以任意填((l>r)时)

    中间两种转移系数都是1,最后一种转移系数为26.对于第一种转移,如果(s_l=s_r),那么还剩下(25)种字符可以填,否则还剩(24)种字符可以填.那么转移把第一种转移先用矩乘预处理出来,然后对于(f_{i,l,r})只用后两种转移,这样贡献答案时(f)的转移系数就只和转移过程中(s_l=s_r)以及(s_l eq s_r)的个数有关.所以(f)多开一维表示(s_l=s_r)的情况个数.贡献答案时假设是枚举(x)(s_l=s_r),那(s_l eq s_r)就假设有(y)个(并且(y)可以由(x)推出来).矩乘预处理第一种转移时,可以看成是一张(DAG),上面有(x+y+1)个点依次连接,转移系数为(1),其中前(x)个点都会有系数为(24)的自环,后(y)个点都会有系数为(25)的自环,最后一个点有(26)的自环,然后要的是走若干步从第一个点到最后一个点的方案,这样子就可以做到(O(n^4log(n+m)))

    然而还是不能通过此题.我们考虑整(n+lceilfrac{n}{2} ceil+lceilfrac{n}{2} ceil)个点(实际上可能还要多几个点,不过规模约为这么大),分别称为(A,B,C)类点,其中每个(A)类点有一个(24)的自环,每个(B)类点有一个(25)的自环,每个(C)类点有一个(26)的自环.然后所有(A)类点顺次连接,后面接着连(B)类点,(B)类点同样依次连接,每个(B)类点下再挂一个(C)类点(其中每条连接两点的边,转移系数为1),大概得到这样的结构

    一般我们矩乘都是行向量乘转移矩阵.现在我们把表示状态的行向量拓展,变成若干行向量,每一行表示从某个点(A)类点出发,到达其他点的方案,那么只要一次矩乘快速幂,然后求第(x)(A)类点到第(y)(C)类点(或者是(B)类点)的方案就是矩阵上(A)类点对应的那一行,(C)类点(或(B)类点)对应的那一列的值.复杂度优化到(O(n^3+n^3log(n+m)))

    code

    CF516E

    下面假装有(nle m).我们可以先做这个操作(m)次,这(m)次里只要做有值的部分即可.那么如果前(m)次操作中第(i)次操作使得上面的点(x)和下面的点(y)都被标记,那么可以发现第(i+m)次操作会使得上面的((x+m)mod n)点被标记,以及发现第(i+n)次操作会使得下面的((y+n)mod m)点被标记,并且可以发现所有的操作影响都可以规约到上面两种情况

    进一步的,根据上面的操作,可以发现这两个序列分别可以分成(gcd(n,m))个环,每个环互相独立,就可以分开考虑了(注意环内每次操作相当于一般情况下(gcd(n,m))次操作,同时还要加上环内第一次操作为一般情况下第几次操作).如果一个环内没有一个初始被标记的点,那就无解,否则一定有解

    后面记(n1=frac{n}{gcd(n,m)},m1=frac{m}{gcd(n,m)}),这其实就是一个环内上下两排的规模.然后在环内可以先进行(m1)次操作,这导致上面一排每个被标记的点(x1)每过(m1)次操作后标记((x1+m1)mod n1)号点,和下面一排每个被标记的点(y1)每过(n1)次操作后标记((y1+n1)mod m1)号点.统计时只需要记录前面的操作中每个被标记的点最早操作的时间,然后对于上面一排,(x1)((x1+m1)mod n1)连边,再把刚刚标记的点放在环上,那么每个点能标记的点都是这个点在环上往后到环上下一个点之前的一段,就对于每个这样的段算出段上的点全被标记的最早时间,下面一排同理,接着一起取个(max)就是这个环的贡献.最后答案为所有环贡献的(max)

    高 级 口 胡 记 录

    code

    CF585E

    here

    CF585F

    由取值在([x,y])中,可以想到求([0,y])的答案减([0,x-1])的答案,那么就是个数位dp

    由出现长度至少为(lfloorfrac{d}{2} floor)的子串,可以想到把所有后缀插入AC自动机后dp

    所以设(f_{i,j,0/1,0/1})表示长度为(i),匹配到自动机(j)号点,当前是否处于危险态,当前是否出现过长度至少为(lfloorfrac{d}{2} floor)的子串的串个数,转移见代码就是AC自动机和数位dp的结合,仔细想想,应该不难

    code

    CF568E

    ( iny ext{题解搬运工})

    这里只要通过放部分数并确定最长的(LIS)就可以了.因为这里是严格上升,所以可以填的每种数最多只会在(LIS)中出现一次,即不需要考虑前面放的数对后面的影响.

    我们不妨考虑(nlogn)(LIS)的方法,维护(f_i)为长度为(i)(LIS)的最小结尾元素,每次对于数(x)找到最大的(i)满足(f_i<x),然后(f_{i+1})(x)取min.如果当前(x)是确定的显然可以直接这样做.否则因为某个位置放数不会受到前面放的数影响,那么所有可以填的数都可以放在这一位置上,对于每个数都跑一遍(x)确定的做法即可考虑从大到小枚举可以填的数,那么对应能放的(i)也是单调不增的,所以可以双指针去扫两个数组,然后用每种可以填的数更新(f),这部分复杂度(O(k(m+n)))可以过(

    最后是构造方案.由于我们不好记录不确定位置的前缀信息,这里可以改成记(LIS)中每个确定位置的上一个在(LIS)中的确定位置.构造时从后往前,对于当前确定位置(x),他到上一个确定位置(y)之间的空位可以填((a_y,a_x))之间的数,那么只要按顺序尽可能的去填出一个上升序列就好了.最后那些还没确定的位置填还没填过的数即可

    code

    CF603E

    首先考虑什么样的边集才合法,这个结论是要使得连上边后所有的连通块点数都为偶数.考虑一个偶连通块,任意选一个生成树,然后按照深度从深到浅考虑,如果当前这个点度数为偶数,那么就选择它到父亲的边.可以发现对于生成树的根,由于总度数之和为偶数,且其他点度数都是奇数,所以根度数也是奇数

    然后由于要使得最大的边最小,所以我们每次求答案时依次考虑还没被删的最大的边,如果这个边删掉后不会改变连通性或者会得到两个偶连通块就可以删.这个可以lct维护最小生成树来实现

    还有个线段树分治的做法.这里可以对于一个询问,一直加边直到没有奇连通块.然后由于答案一定是单调不增的,所以如果从后往前考虑,然后维护当前可用的边以及图连通性,如果还存在奇连通块就把当前没加入的最小的边加入,这样每条边存在的时间段是它出现时间到被这个过程加入的时间,所以可以线段树分治加可撤销并查集从后往前做

    code

  • 相关阅读:
    【转】K/3 KIS BOS 插件入门
    [转]SQL Server 存储过程中使用 in 动态变量
    [转]Delphi 12种大小写转换的方法
    cxGrid FilterRow 添加左模糊查询,实现 %ABC%
    cxGrid 锁定一行,让该行数据不能编辑
    K/3工业单据K3BillTransfer的属性及使用方法
    VB6上创建金蝶K/3或KIS旗舰版插件
    MySQL UTF8 中文乱码处理
    两种方法自动部署代码:webhooks钩子自动部署代码方法一 及定时任务自动部署二 简介
    Linux查看进程的4种方法
  • 原文地址:https://www.cnblogs.com/smyjr/p/12085128.html
Copyright © 2011-2022 走看看