2019 国际大学生程序设计竞赛(ICPC)亚洲区域赛(银川) 7题

news2024/9/22 13:30:08

文章目录

      • N.Fibonacci Sequence
      • B.So Easy
      • I.Base62
      • G.Pot!!
      • F.Function!
      • K.Largest Common Submatrix

补题链接:https://codeforces.com/gym/104021
难得VP打出这么好的成绩,虽然是有争议的西部枢纽银川站,虽然没能早生几年。。。。

在这里插入图片描述
在这里插入图片描述

N.Fibonacci Sequence

题意:

  • 输出斐波那契数列的前5项

思路:

  • 输入没有,输出是前五项,直接样例复制粘贴输出就过了。
#include<bits/stdc++.h>
using namespace std;

int main(){
    cout<<"1 1 2 3 5\n";
    return 0;
}

B.So Easy

题意:

  • 给出一个n*n的矩阵,初始全为0。每次可以选择任意行或任意列,给整行+1。
  • 若干次操作后得到一个全新的矩阵。
  • 将该矩阵的某个位置藏起来(设为-1),并把该矩阵作为输入给你,求那个藏起来的值是多少。

思路:

  • 不难发现任意二元子矩阵的对角线和是相等的。 将4个点分成两组,不管加哪一行还是哪一列,刚好每组都会恰好有1个点被加到1次。
  • 所以答案就是找个包含-1的随便矩阵,然后a[x,y] = a[x+1,y]+a[x,y+1]-a[x+1,y+1]。
  • 考虑到4个顶点的位置,所以分一下类。开始没关流同步,TLE5了一发。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int a[maxn][maxn];

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int n;  cin>>n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            cin>>a[i][j];
        }
    }
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= n; j ++ ) {
            if (a[i][j] == -1) {
                if (i > 1 && j > 1) {
                    a[i][j] = a[i - 1][j] + (a[i][j - 1] - a[i - 1][j - 1]);
                } else if (i > 1 && j < n) {
                    a[i][j] = a[i - 1][j] + (a[i][j + 1] - a[i - 1][j + 1]);
                } else if (i < n && j > 1) {
                    a[i][j] = a[i + 1][j] + (a[i][j - 1] - a[i + 1][j - 1]);
                } else {
                    a[i][j] = a[i + 1][j] + (a[i][j + 1] - a[i + 1][j + 1]);
                }
                cout << a[i][j] << '\n';
                return 0;
            }
        }
    }
    return 0;
}

I.Base62

题意:

  • 给出一个x进制下的数z,将它转为y进制输出。(0-9,大写,小写字母依次表示到62进制)

思路:

  • 先转10进制,再转y进制,直接输出即可。
  • 120次方需要手写高精度,直接python大整数即可。
  • 开始0没特判,WA12了一发。
x, y, z = input().split()
x = int(x); y = int(y)
tmp = 0
for i in z :
    if i >= '0' and i <= '9':
        tmp = tmp * x +  int(i)
    elif i >= 'A' and i <= 'Z' :
        tmp = tmp * x + 10 + ord(i) - 65
    else :
        tmp = tmp * x + ord(i) + 36 - 97
res = ""
while tmp > 0 :
    tp = tmp % y
    tmp = tmp // y
    if (tp <= 9) : res = str(tp) + res
    elif (tp < 36) : res = chr(tp - 10 + 65) + res
    else : res = chr(tp - 36 + 97) + res
if res == "" : print(0)
else : print(res)

G.Pot!!

题意:

  • 定义函数pop_p(n) = m,其中p为n的因数,m表示该因数的个数。
  • 题目有两种操作。
    操作1:给区间[l, r]都乘上一个x(x<10)
    操作2:求区间内任意一个数的因数个数最大的个数。例如对于ai的所有因数出现次数分别为b1, b2, b3, ,bn, 取max{b1。。。。bn}。 然后再取max{al。。。。ar}。
  • n<1e5, 操作q<1e5

思路:

  • 发现乘的数x属于1到10, 而1-10内的质因数只有2,3,5,7四种情况。加上数组初始值为1,相当于最后任意情况下的数组,每个值都只有2357这四个质因数。
  • 区间操作和区间查询不难想到线段树,加上查询的时候查的只有质因数个数的最大值,我们不难想到维护4个线段树,分别表示2,3,5,7的区间最大值。 修改的时候对于输入的x质因数分解,然后给对应的线段树做区间加即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1000010;
int n, m, k;

int tree[5][N];
int lazy[5][N];
void push_down(int id, int l, int r, int u) {
    int mid = (l + r) >> 1;
    tree[id][u << 1] += lazy[id][u];
    lazy[id][u << 1] += lazy[id][u];
    tree[id][u << 1 | 1] += lazy[id][u];
    lazy[id][u << 1 | 1] += lazy[id][u];
    lazy[id][u] = 0;
}
void update(int id , int l, int r, int u, int L, int R, int v) {
    if (l > R || r < L) return;
    if (l >= L && r <= R) {
        tree[id][u] += v;
        lazy[id][u] += v;
        return;
    }
    if (lazy[id][u]) {
        push_down(id, l, r, u);
    }
    int mid = (l + r) >> 1;
    update(id, l, mid, u << 1, L, R, v);
    update(id, mid + 1, r, u << 1 | 1, L, R, v);
    tree[id][u] = max(tree[id][u << 1], tree[id][u << 1 | 1]);
}
int query(int id, int l, int r, int u, int L, int R) {
    if (l > R || r < L) return 0;
    if (l >= L && r <= R) {
        return tree[id][u];
    }
    if (lazy[id][u]) {
        push_down(id, l ,r , u);
    }
    int mid = (l + r) >> 1;
    return max(query(id, l, mid, u << 1, L, R), query(id, mid + 1, r, u << 1 | 1, L, R));
}
void solved() {
    cin >> n >> m;
    for (int i = 1; i <= m; i ++ ) {
        string opr;
        int l, r;
        cin >>opr >> l >> r;
        if (opr == "MULTIPLY") {
            int x;
            cin >> x;
            while (x % 2 == 0) update(0, 1, n, 1, l, r, 1), x /= 2;
            while (x % 3 == 0) update(1, 1, n, 1, l, r, 1), x /= 3;
            while (x % 5 == 0) update(2, 1, n, 1, l, r, 1), x /= 5;
            while (x % 7 == 0) update(3, 1, n, 1, l, r, 1), x /= 7;
        } else {
            int maxn = 0;
            for (int i = 0; i <= 3; i ++ ) {
                maxn = max(maxn, query(i, 1, n, 1, l, r));
            }
            cout <<"ANSWER " <<  maxn << '\n';
        }
    }
}

signed main() {
    int t = 1;
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    // cin >> t;
    for (int i = 1; i <= t; i ++ ) {
        solved();
    }
}

F.Function!

题意:

  • 定义fa(x)=a^x,f-1a(x)为fa(x)的反函数。
  • ∑ a = 2 n ( a ∑ b = a n ⌊ f a − 1 ( b ) ⌋ ⌈ f b − 1 ( a ) ⌉ ) \sum_{a=2}^n(a\sum_{b=a}^n⌊f_a^{−1}(b)⌋⌈f_b^{−1}(a)⌉) a=2n(ab=anfa1(b)fb1(a)) % 998244353 的结果。

思路:

  • 输入一个数,输出一个数,n的范围是1e12,盲猜结论题,打了波表,发现样例都打不出来。
  • fa(x)的反函数就是log(a)b, 且a<=b对原式必成立,所以log(b)a肯定是介于0与1之间的,向上取整后必然等于1。
    此时去掉这部分修改后的打表成功了,虽然还是没找到什么规律,但是发现做两次差分后,后面的值都是成段出现的,意识到左边的部分,loga(b)他其实是可以用数论分块做的,因为b在一段区间内,log(a)b的值都是相同的。
  • 但是复杂度还是不够,进一步推式子,发现当a>1e6的时候,log1e6(1e12)也才等于2,意味着左边的式子log(a)b也恒等于1了,此时就变成了一个等差数列求和公式,即可求出来。
  • 而对于<1e6(或者说根号n)的部分,第二层循环跑分块的复杂度只有十几,乘上外面的1e6,是可以通过的。
#include <bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1000010;
int n, m, k;
const int mod = 998244353;
int Qpow(int x, int k) {
    int res = 1;
    while (k) {
        if (k % 2) res = (res * x) % mod;
        x = (x * x) % mod;
        k >>= 1; 
    } 
    return res;
}
int get_presum(int x) {
    x = x % mod;
    int len = n % mod;
    int part1 = len % mod * (1 + x) % mod * x % mod * Qpow(2, mod - 2) % mod;
    int part2 = (2 * x % mod + 1) * (x + 1) % mod * x % mod * Qpow(6, mod - 2) % mod;
    int part3 = (1 + x) % mod * x % mod * Qpow(2, mod - 2) % mod;
    // cout << part1 << " " << part2 << ' ' << part3 << '\n';
    return (part1 - part2 + part3) % mod; 
}
void solved() {
    cin >> n;
    int res = 0;
    for (int i = 2; i * i <= n; i ++ ) {
        int tmp = 1;
        int sum = 0;
        for (int j = i; j <= n; j *= i) {
            sum = (tmp * (min(n + 1, j * i) - j) % mod + sum) % mod;
            tmp ++;
        }
        res = (res + i * sum % mod) % mod;
    }
    int r = sqrt(n);
    res = (res + get_presum(n) - get_presum(r) + mod) % mod;
    cout << res << '\n';
}

signed main() {
    int t = 1;
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    // cin >> t;
    for (int i = 1; i <= t; i ++ ) {
        solved();
    }
}


K.Largest Common Submatrix

题意:

  • 给出两个n*m的矩阵A和B,矩阵的值由1-nm的排列打乱后组成(不重复)。
  • 求矩阵A和矩阵B的最大公共子矩阵。
  • n,m<1000

思路:

  • 类比全为排列的最长公共子串的复杂度最优的做法为, 将序列A映射到序列B,然后对序列B做最长上升子序列。本题也可以将矩阵A映射到矩阵B,(不难证明在A和B中同时交换任意两个数字的位置时, 新的两个矩阵的LCS对结果是不会产生影响的。),即将矩阵A修改为123456.。。。。nm的形式,然后B对应的修改为某个新的随机矩阵。
  • 考虑映射后的矩阵B,要找他和A的最大公共子矩阵,只需要满足某个值向上延伸都是-m的情况,向左延伸都是-1的情况。按照这种方法向四个方向蔓延出去,能取到的矩阵面积最大即可。此时枚举点和方向的复杂度为O(n^4)。
  • 不难递推预处理出top[i][j]表示第i行第j个从当前往上蔓延能走到的最远的距离,对于某一行,这样的top[i]这一行数组就形成了一个柱状图求最大面积的情况,发现白书里做过,是POJ2559原题,可以单调栈做。
    参考:https://gwj1314.blog.csdn.net/article/details/81513728
  • 然后写完没过样例,发现有点不一样的地方是,直接按没列跑单调栈,没有考虑到行的情况,所以在行上再做一个递推,对行上的各个区间,分别跑单调栈求最大面积(相当于遇到断掉的时候就清空栈一次),然后就AC了。
#include <bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1000010;
int n, m, k;
const int mod = 998244353;
pair<int, int> pos[N];
int mrxa[1002][1992], mrxb[1002][1090];
int top[1010][1010];
int vis[N];
void solved() {
    cin >> n >> m;
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) {
            cin >> mrxa[i][j];
            vis[mrxa[i][j]] = (i - 1) * m + j;
        }
    }
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) {
            cin >> mrxb[i][j];
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            mrxb[i][j] = vis[mrxb[i][j]];
        }
    }
    int maxn = 0;
    stack<int> st;
    for (int i = 1; i <= n; i ++ ) {
        st.push(0);
        int last[1002];
        for (int i = 1; i <= m; i ++ ) last[i] = m + 1; 
        for (int j = 1; j <= m; j ++ ) {
            if(mrxb[i-1][j]+m==mrxb[i][j]){
                top[i][j] = top[i-1][j]+1;
            }else{
                top[i][j] = 1;
            }
            if (mrxb[i][j - 1] + 1 != mrxb[i][j]) {
                while (st.top() != 0) {
                    maxn = max(maxn, (j - last[st.top()]) * top[i][st.top()]);
                    st.pop();
                }
            }
            last[j] = j;
            while (top[i][j] <= top[i][st.top()]) {
                maxn = max(maxn, (j - last[st.top()]) * top[i][st.top()]);
                last[j] = min(last[st.top()], last[j]);
                st.pop();
            }
            st.push(j);
        }
        while (st.top() != 0) {
            maxn = max(maxn, (m + 1 - last[st.top()]) * top[i][st.top()]);
            st.pop();
        }
    }
    cout << maxn << '\n'; 
}

signed main() {
    int t = 1;
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    // cin >> t;
    for (int i = 1; i <= t; i ++ ) {
        solved();
    }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32954.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】基础:堆

【数据结构】基础&#xff1a;堆 摘要&#xff1a;本文主要介绍数据结构堆&#xff0c;分别介绍其概念、实现和应用。 文章目录【数据结构】基础&#xff1a;堆一、概述1.1 概念1.2 性质二、实现2.1 定义2.2 初始化与销毁2.3 入堆2.4 出堆2.5 堆的创建2.6 其他三、应用3.1 堆排…

《前端》css总结(下)

文章目录元素展示格式displaywhite-spacetext-overflowoverflow内边距和外边距marginpadding盒子模型box-sizing位置position&#xff1a;用于指定一个元素在文档中的定位方式浮动flex布局flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-contentorderflex-g…

你最少用几行代码实现深拷贝?

问题分析 深拷贝 自然是 相对 浅拷贝 而言的。 我们都知道 引用数据类型 变量存储的是数据的引用&#xff0c;就是一个指向内存空间的指针&#xff0c; 所以如果我们像赋值简单数据类型那样的方式赋值的话&#xff0c;其实只能复制一个指针引用&#xff0c;并没有实现真正的数…

计算机组成原理4小时速成:存储器,内存ROM,RAM,Cache,高速缓存cache,外存,缓存命中率,效率

计算机组成原理4小时速成&#xff1a;存储器&#xff0c;内存ROM,RAM,Cache&#xff0c;高速缓存cache&#xff0c;外存&#xff0c;缓存命中率&#xff0c;效率 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法…

MYSQL事务原理分析

目录事务是什么ACID特性原子性&#xff08;A&#xff09;隔离性&#xff08;I&#xff09;持久性&#xff08;D&#xff09;一致性&#xff08;C&#xff09;隔离级别简介有些什么READ UNCOMMITTED&#xff08;读未提交&#xff09;READ COMMITTED&#xff08;读已提交&#xf…

【17】Java常见的面试题汇总(设计模式)

目录 1. 说一下你熟悉的设计模式&#xff1f; 2. 简单工厂和抽象工厂有什么区别&#xff1f; 1. 说一下你熟悉的设计模式&#xff1f; 单例模式&#xff1a;保证被创建一次&#xff0c;节省系统开销。 工厂模式&#xff08;简单工厂、抽象工厂&#xff09;&#xff1a;解耦…

力扣(LeetCode)60. 排列序列(C++)

枚举 枚举每一位可能的数字。 如图。算法流程如上图。 思路分析 : 一个数 nnn &#xff0c;可以组成的排列数量有 n!n!n! 。当首位确定&#xff0c;剩余位能组成的排列数量 (n−1)!(n-1)!(n−1)! &#xff0c;依次类推 (n−2)!/(n−3)!/(n−4)!/…/2!/1!/0!(n-2)!/(n-3)!/(n…

CentOS7安装MYSQL8.X的教程详解

1-首先查看系统是否存在mysql&#xff0c;无则不返回 1 # rpm -qa|grep mysql 2-安装wget 1 # yum -y install wget 3-抓取mariadb并删除包&#xff0c;无则不返回 1 # rpm -qa|grep mariadb 4-删除mariadb-libs-5.5.68-1.el7.x86_64 1 # rpm -e --nodeps mariadb-libs-…

本节作业之数组求和及其平均值、求数组最大值、最小值、数组转换为分割字符串、新增数组案例、筛选数组案例、删除指定数组元素、翻转数组、数组排序(冒泡排序)

本节作业之数组求和及其平均值、求数组最大值、最小值、数组转换为分割字符串、新增数组案例、筛选数组案例、删除指定数组元素、翻转数组、数组排序<冒泡排序>求数组[2,6,1,7,4]里面所有的元素的和以及平均值求数组[2,6,1,77,52,25,7]中的最大值求数组[2,6,1,77,52,25,7…

Linux - netstat 查看系统端口占用和监听情况

文章目录功能语法示例显示 tcp&#xff0c;udp 的端口和进程Show both listening and non-listening socketsList all tcp ports.List all udp portsList only listening portsList only listening TCP ports.List only listening UDP ports.List only the listening UNIX port…

Android 性能优化方法论【总结篇】

作为一位多年长期做性能优化的开发者&#xff0c;在这篇文章中对性能优化的方法论做一些总结&#xff0c;以供大家借鉴。 性能优化的本质 首先&#xff0c;我先介绍一下性能优化的本质。我对其本质的认知是这样的&#xff1a;性能优化的本质是合理且充分的使用硬件资源&#x…

分享感恩节联系客户话术

看了一眼在手边的日历&#xff0c;发现今天是11月24日&#xff0c;一年一度的感恩节又到了&#xff0c;不得不感叹时间过得真快&#xff0c;每年十一月的第四个星期四是感恩节。 随着各国多元文化的发展&#xff0c;感恩节也越来越被世界各地传颂&#xff0c;多少都会有一些影…

WANLSHOP 直播短视频种草多用户电商系统源码自营+多商户+多终端(H5+小程序+APP)

WANLSHOP高级版 可用于自营外包项目(多主体)、 可用于外包定制开发项目、 提供开源源码&#xff0c;私有化部署、一款基于 FastAdmin Uni-APP 开发的 多终端&#xff08;H5移动端、APP、微信小程序、微信公众号&#xff09;、多用户商城系统拥有多种运营模式B2B2C/B2C&#xf…

python安装依赖库

一、安装pip 1、打开终端&#xff0c;输入&#xff1a; pip3 install tushare -i https://pypi.douban.com/simple 2、验证是否安装成功 打开终端&#xff0c;输入&#xff1a;pip3 出现以上页面&#xff0c;则安装成功 二、安装flask 1、打开终端&#xff0c;输入&…

mybatis-plus学习笔记

文章目录1 简介2 初始化项目2.1引入pom2.2 引入lombok插件2.3 配置信息2.4 创建实体类2.5 创建mapper2.6 配置注解MapperScan2.7 编写测试类2.8 配置MyBatis日志3 测试基本的CRUD3.1 新增3.2 查询3.3 修改3.4 删除4 自定义动态sql5 Service 层使用mybatis-plus方法5.1 service层…

使用hive进行大数据项目分析

目录 一、首先要创建表&#xff1a;在txt记事本中先输入创建语句备用&#xff0c;创建class1~class5的表。 二、启动hadoop集群&#xff0c;MySQL&#xff0c;hive。 三、创建数据库zhh&#xff0c;用户为zhh&#xff0c;之后将之前写在txt记事本里的创建表class1~class5的命…

浅谈企业信息化安全建设中的三大误区

伴随着信息化的深度建设与应用&#xff0c;与之相伴的信息安全事件也层出不穷&#xff01;很多企业开始关注信息安全问题、关注信息安全建设&#xff0c;大家的共识已经达到前所未有的高度。 虽然许多的企业虽然认识到信息安全的重要性&#xff0c;在实际实施过程中却又无从下…

【附源码】计算机毕业设计JAVA亦心化妆品网站

【附源码】计算机毕业设计JAVA亦心化妆品网站 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JAVA myba…

【软件测试】我们测试人搭上元宇宙的列车,测试一直在进军......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 虚拟宇宙&#xff0…

微信抽奖小程序开发_分享微信抽奖小程序制作的步骤

各位商家在节日期间做活动的时候&#xff0c;都希望用更少的费用去或者更好的宣传和推广的效果。比较常见的就是抽奖活动小程序。无须玩家下载&#xff0c;通过微信扫码或者指定入口就可以参与。 方便&#xff0c;效果又好。 那么,性价比高的抽奖活动小程序怎么做&#xff1f…