AtCoder ABC150

C题
签到题。会python的permutations 或者C++的next_permutation就能做。

D题
乍一看很简单,把所有元素折半求最小公倍数lcm,然后求lcm的奇数倍即可。但是有坑:
比如6 4这种情况,lcm=6 但6=61 6=41.5,因此无法满足要求。原因是4折半后为2,导致求得的lcm可以被2整除,如6/2不为半数。去掉这种情况就能AC。

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @file     : atcoder.py
# @software : PyCharm

import bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(200050)


def gcd(x, y):
    if x > y:
        x, y = y, x
    while x:
        x, y = y % x, x
    return y


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    n, m = map(int, fp.readline().split())
    a = list(map(int, fp.readline().split()))
    for i in range(n):
        a[i] = a[i] // 2
    gm = a[0]
    for i in range(1, n):
        g = gcd(a[i], gm)
        gm = gm // g * a[i]

    for i in range(n):
        if (gm // a[i]) % 2 == 0:
            print(0)
            return

    ans = m // gm - (m // (2 * gm))
    print(ans)


if __name__ == "__main__":
    main()

E题
下面两个很不错的题。
本题考察如何按位置来计数。首先题目可以把 f ( S , T ) f(S,T) f(S,T)转换为求 f ( S ) = S ⊕ T f(S)=S \oplus T f(S)=ST下按照原规则计算,然后答案乘上 2 n 2^n 2n
如 第二个例子中 5 8
可以看到以下 2 2 2^2 22组是等价的
( 1 , 0 ) , ( 0 , 0 ) (1,0) ,(0,0) (1,0),(0,0)
( 0 , 0 ) , ( 1 , 0 ) (0,0),(1,0) (0,0),(1,0)
( 1 , 1 ) , ( 0 , 1 ) (1,1),(0,1) (1,1),(0,1)
( 1 , 0 ) , ( 0 , 0 ) (1,0),(0,0) (1,0),(0,0)
现在原题就转换为求 s ∈ 0... 2 n s \in {0...2^n} s0...2n f ( s ) f(s) f(s)之和。
显然c应该从大到小排序。

如果按照每个c从第一位到第n位来计数,那么不难利用组合数推出一个 O ( n 2 ) O(n^2) O(n2)算法。但是时间不够。

比较巧妙的计数方法是将每一位的计算拆开来。
假设当前已经到了第i位(i从1开始计数)
例如要求的c数组长度为3,可以列出8个异或值。
1 , 1 , 1 1 , 0 , 0 1 , 0 , 1 1 , 1 , 0 0 , 0 , 0 0 , 0 , 1 0 , 1 , 0 0 , 1 , 1 1,1,1\\1,0,0\\1,0,1\\1,1,0\\0,0,0\\0,0,1\\0,1,0\\0,1,1 1,1,11,0,01,0,11,1,00,0,00,0,10,1,00,1,1
看第3位,他对答案的贡献是3+2+1+2=8(从上往下)
我们可以将其拆成两部分,第一部分是“只要填了1就可以贡献1”
由于这部分和其他无关,因此贡献值一共为 2 n − 1 2^{n-1} 2n1
第二部分是“前面的某一位填了1因此要多贡献1”
这部分仅仅和前面的那一位相关(当然这一位也要填1),因此贡献值是 2 n − 2 ∗ ( i − 1 ) 2^{n-2}*(i-1) 2n2(i1)
这样答案就已经出来了。
回到样例,例如第一组 1 , 1 , 1 1,1,1 1,1,1中,第一部分贡献1,第二部分分别由前面的数字贡献了1+1,因此是3;第三组 1 , 0 , 1 1,0,1 1,0,1中,第一部分贡献1,第二部分由第一位1贡献了1,因此是2.

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @file     : atcoder.py
# @software : PyCharm

import bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(200050)


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    n = int(fp.readline())
    a = list(map(int, fp.readline().split()))
    a.sort(reverse=True)
    mod = 10 ** 9 + 7

    pw = [1] * (n + 1)
    for i in range(1, n + 1):
        pw[i] = pw[i - 1] * 2 % mod

    ans = 0
    for i in range(n):
        ans += (pw[n - 1] + pw[n - 2] * i) * a[i]
    ans = ans * pw[n] % mod
    print(ans)


if __name__ == "__main__":
    main()

F题
看到这种求shift的题,第一感觉一定是将匹配串重复一遍。
好吧,既然说到了模式串和匹配串,那么不得不说到kmp。单纯的kmp似乎没什么思路,但是如果将每个数组相邻的数进行异或操作,就变成了kmp模板题。

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @file     : atcoder.py
# @software : PyCharm

import bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(1000)


def get_next(p):
    p = [0] + list(p)
    m = len(p)
    ne = [0] * m
    i, j = 2, 0
    while i < m:
        while j and p[i] != p[j + 1]:
            j = ne[j]
        if p[i] == p[j + 1]:
            j += 1
        ne[i] = j
        i += 1
    return ne


def kmp_match(s, p, ne):
    s = [0] + list(s)
    p_len = len(p)
    p = [0] + list(p)
    i, j = 1, 0
    n, m = len(s), len(p)
    m_list = []
    while i < n:
        while j and j + 1 < m and s[i] != p[j + 1]:
            j = ne[j]
        if j + 1 < m and s[i] == p[j + 1]:
            j += 1
        if j == p_len:
            bi, ei = i - p_len + 1, i
            j = ne[j]
            m_list.append(bi - 1)
        i += 1
    return m_list


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    n = int(fp.readline())
    a = list(map(int, fp.readline().split()))
    b = list(map(int, fp.readline().split()))
    a = a + a
    da, db = [], []
    for i in range(2 * n - 2):
        da.append(a[i + 1] ^ a[i])
    for i in range(n - 1):
        db.append(b[i + 1] ^ b[i])
    ne = get_next(db)
    m_list = kmp_match(da, db, ne)
    for i in m_list:
        print(i, a[i] ^ b[0])


if __name__ == "__main__":
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值