Codeforces Round 917 (Div. 2)(A~D)(又是数学题)

news2024/9/29 9:39:08

A - Least Product 

        题意:

思路:若有奇数个负数,则不需要任何操作。若存在0,也不需要任何操作。其余情况将任意一个数改为0即可。

        

#include <bits/stdc++.h>
using namespace std;
void solve() 
{
	int n;
	cin >> n;
	int a[n + 5];
	for(int i = 0 ; i < n ; i ++)
		cin >>a[i];
	int cnt = 0;
	for(int i = 0 ; i < n ; i ++){
		if(a[i] < 0){
			cnt++;
		}
		if(a[i] == 0){
			cout << 0 <<endl;
			return;
		}
	}
	if(cnt % 2 == 0){
		cout << 1 << endl;
		cout << 1 << " " << 0 << endl;
	}
	else{
		cout << 0 <<endl;
	}
}            
int main() 
{
    int t = 1;
	cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

B - Erase First or Second Letter 

        题意:

        思路:由于只能删除前两个数,因此可以考虑固定字符串开头,然后每次删除第二个数就会多形成一个空字符串。然后遍历每一个字符,这样做是O(N^{2})的。可以发现:对于同一个开头字母而言,前面位置删除后所能形成的字符串必然涵盖了后面位置开头所形成的字符串,因此不需要遍历所有字符,只需要遍历所有字母即可。这样复杂度是 O(26 * N)的。

#include <bits/stdc++.h>
using namespace std;
void solve() 
{
	int n;
	string s;
	cin >> n;
	int inf = n + 1;
	cin >> s;
	vector<int>P(26 , inf);
	for(int i = 1 ; i <= n ; i ++){
		P[s[i - 1] - 'a'] = min(P[s[i - 1] - 'a'] , i);
	}	
	int ans = 0;
	for(int i = 0 ; i < 26 ; i ++){
		ans += inf - P[i];
	}
	cout << ans <<endl;
}            
int main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int t=1;
	cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

C - Watering an Array 

        题意:

               思路:假设一开始数组全为0,要让a_{j} = j的最少操作需要j次,且有\forall i(a_{i} = j > i)(i < j)\forall i(a_{i} <= j < i)(i > j),因此整个数组的价值最多为1。由此可以发现,对于全是0的数组而言,只需要前一天选择操作1,让a_{1} = 1 , 第二天选择操作2。这样就能得1分,且这么做一定是最优的。由于一开始不一定全是0,所以在第一次使用操作2了之后,每两天能够得一分。接下来只需要枚举什么时候第一次用操作2就行了。

        假设第 i 天第一次使用操作2,那么总共的得分为 初始数组得分 + (d - i) /2。而什么情况下会使得总得分更高,即连续使用操作1之后,初始数组得分变的更高了。由于初始数组得分最高为n,所以只需要遍历前2 * n天使用操作1即可。复杂度为O(2 * N^{2})

        

#include <bits/stdc++.h>
using namespace std;
const int inf = 100;
void solve() 
{
	int n , k , d;
	cin >> n >> k >> d;
	int arr[n + 5] , brr[k + 5];
	for(int i = 1 ; i <= n ; i ++){
		cin >> arr[i];
	}
	for(int i = 0 ; i < k ; i ++){
		cin >> brr[i];
	}
	int ans = -inf;
	int dd = 0;
	for(int i = 0 ; i < min(d , 2 * n) ; i ++){
		int num = 0;
		for(int j = 1 ; j <= n ; j ++){
			num += (arr[j] == j);
		}
		ans = max(ans , num + (d - 1 - i) / 2);
		for(int j = 1 ; j <= brr[dd] ; j ++){
			arr[j]++;
		}
		dd++;
		dd %= k;
	}
	cout << ans << endl;
}            
int main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int t=1;
	cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

D - Yet Another Inversions Problem

思路: 对于一个数内部,即a_{ik}a_{ik + k - 1}之间的逆序对而言,只需要对q数组求一次逆序对即可。

  接下来考虑数与数之间的情况。对于a_{i}而言,大小在(a_{i} , 2 * a_{i})之间的数而言,a_{i}*2^{p_{j}}与这些数能够形成的逆序对为(a_{i}*2^{p_{j}} , a_{x} * 2^{p_{j} - 1})(a_{i}*2^{p_{j}} , a_{x} * 2^{p_{j} - 2})....(a_{i}*2^{p_{j}} , a_{x} * 2^{0})总共有p_{j}个。因此a_{i}与这些数所能形成的逆序对数量为\sum_{i = 0}^{k} p_{i} = (0 + k - 1) * k / 2。而对于大小在(2 * a_{i} , 4 * a_{i})的数而言,a_{i}*2^{p_{j}}与这些数能够形成的逆序对为(a_{i}*2^{p_{j}} , a_{x} * 2^{p_{j} - 2})(a_{i}*2^{p_{j}} , a_{x} * 2^{p_{j} - 3})....(a_{i}*2^{p_{j}} , a_{x} * 2^{0})总共有p_{j} - 1。因此因此a_{i}与这些数所能形成的逆序对数量为\sum_{i = 0}^{k} p_{i} = (0 + k - 2) * (k - 1) / 2,如此不断往上倍增求答案,直到上限为止。

        而相反,大小在((a_{i}+ 1)/ 2, a_{i})之间的数而言,也是同样的考虑方式,如此不断除以二直到下限为止。详细可以看注释

        

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define int long long
const LL mod = 998244353;
const int N = 5e5;
struct BIT{//Binary indexed Tree(树状数组)
	int n;
	vector<int> tr;
	BIT(int n) : n(n) , tr(n + 1 , 0){
	}
	int lowbit(int x){
		return x & -x;
	}
	void modify(int x , int modify_number){
		for(int i = x ; i <= n ; i += lowbit(i)){
			tr[i] += modify_number;
		}
	}
	void modify(int l , int r , int modify_number){
		modify(l , modify_number);
		modify(r + 1 , -modify_number);
	}
	int query(int x){
		int res = 0;
		for(int i = x ; i ;  i -= lowbit(i))
			res += tr[i];
		return res;
	}
	int query(int x , int y){
		return query(y) - query(x);
	}
};
int tmp[N];
LL merge_sort(int q[], int l, int r)
{
    if (l >= r) return 0;
    
    int mid = (l + r) >> 1; // 二分区间
    
    LL res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
    //归并
    int i = l, j = mid + 1, k = 0;
    
    while (i <= mid && j <= r)
    {
        if (q[i] <= q[j]) tmp[k ++] = q[i ++]; // 前面的排序正常,注意`=` 说明不是逆序对
        else
        {
            res += mid - i + 1;
            tmp[k ++] = q[j ++];
        }
    }
    
    // 扫尾工作
    while (i <= mid) tmp[k ++] = q[i ++];
    while (j <= r) tmp[k ++] = q[j ++];
    
    for (int i = l, j = 0; i <= r; i ++ , j ++) q[i] = tmp[j];
    
    return res;
}
void solve() 
{
	int n , k;
	cin >> n >> k;
	BIT num(4 * n + 5) , sum(k + 5);
	int a[n] , b[k];
	for(int i = 0 ; i < n ; i ++){
		cin >> a[i];
		num.modify(a[i] , 1);
	}
	for(int i = 0 ; i < k ; i ++){
		cin >> b[i];
	}
	int ans = merge_sort(b , 0 , k - 1);//自己内部的贡献
	ans *= n;//
	ans %= mod;
	for(int i = 0 ; i < n ; i ++){
		int x = a[i];//x 与 后面所形成的的逆序对
		int cnt = 1;
		while(x < 2 * n ){
			int t = x * 2;
			int nn = num.query(x , t);//a[i] * 2 ^ cnt > 这些数
			if(nn == 0){
				x = t;
				cnt++;
				continue;
			}
			int end = max(1LL * 0 , k - cnt);
			int ns = (1 + end) * end / 2;
		//	cout << x << " " << t << " " << nn << endl;
	//		cout << "cnt :" << cnt <<"ns :" << ns << endl;
			ans += ns * nn;
			ans %= mod;
			x = t;
			cnt++;
		}
		x = a[i];
		cnt = 1;
		while(1){
			if(x == 1)
				break;
			int t = (x + 1) / 2;
			int nn = num.query(t - 1  , x - 1);//这些数 * 2 ^ cnt > a[i]
/*			cout << t - 1 << " " << x - 1 << " " << nn << endl;*/
			if(nn == 0){
				x = t;
				cnt++;
				continue;
			}
			int st = min(k , cnt );//
			int cntt = k - st + 1;
			int res = k - cntt;
			int ns =  k * res + (st + k) * cntt / 2;
/*			cout << "cnt :" << cnt <<"ns :" << ns << endl;*/
			ans += nn * ns;
			ans %= mod;;
			x = t;
			cnt++;
		}
		num.modify(a[i] , -1);
	}
	cout << ans << endl;
}            
signed main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int t=1;
	cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

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

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

相关文章

CUMT--Java复习--网络编程

目录 一、Java网络API 1、InetAddress类 2、URL类 3、URLConnection类 4、URLDecoder类和URLEncoder类 二、基于TCP的网络编程 1、Socket类 2、ServerSocket类 三、网络通信过程 一、Java网络API Java中有关网络方面的功能都定义在java.net中。 1、InetAddress类 Jav…

MySQL undo日志精讲3-从回滚段中申请 Undo 页面链表

回滚段-Rollback Segment Header 页面 回滚段的概念 我们现在知道一个事务在执行过程中最多可以分配4个 Undo 页面链表&#xff0c;在同一时刻不同事务拥有的 Undo 页面链表是不一样的&#xff0c;所以在同一时刻系统里其实可以有许许多多个 Undo 页面链表存在。为了更好的管…

工业互联网:数字化制造的未来

引言 在当今的数字化时代&#xff0c;制造业正经历着革命性的变革。工业互联网&#xff08;Industrial Internet of Things"&#xff0c;简称 IIoT&#xff09;作为这一变革的核心引擎&#xff0c;正在重新定义现代工业和制造。本文将探讨工业互联网的基础、关键技术、应…

论文润色的原理是什么 PaperBERT

大家好&#xff0c;今天来聊聊论文润色的原理是什么&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 标题&#xff1a;论文润色的原理――探究论文润色背后的科学依据 一、…

第十五节TypeScript 接口

1、简介 接口是一系列抽象方法的声明&#xff0c;是一些方法特征的集合&#xff0c;这些方法都应该是抽象的&#xff0c;需要有由具体的类去实现&#xff0c;然后第三方就可以通过这组抽象方法调用&#xff0c;让具体的类执行具体的方法。 2、接口的定义 interface interface_…

利用STM32和可控硅控制220V加热电路

利用STM32和可控硅控制220V加热电路 Chapter1 利用STM32和可控硅控制220V加热电路一、错误原理图二、正确原理图 Chapter2 可控硅驱动芯片MOC3081/3061Chapter3 一个MOC3061的可控硅触发电路的分析Chapter4 可控硅的两种触发方式&#xff1a;移相触发和过零触发1、过零触发2、移…

C++面试宝典第9题:找出第K大元素

题目 给定一个整数数组a,同时给定它的大小N和要找的K(1 <= K <= N),请根据快速排序的思路,找出数组中第K大的数(保证答案存在)。比如:数组a为[50, 23, 66, 18, 72],数组大小N为5,K为3,则第K大的数为50。 解析 这道题主要考察应聘者对于快速排序的理解,以及实…

​【C语言】乘法表

题目要求&#xff1a; 实现一个函数&#xff0c;打印乘法口诀表&#xff0c;口诀表的行数和列数自己指定 如&#xff1a;输入9&#xff0c;输出9 * 9口诀表&#xff0c;输出12&#xff0c;输出12 * 12的乘法口诀表。 题目分析&#xff1a; 我们观察乘法口诀表可以发现&#x…

【重点!!!】【堆】215.数组中的第K个最大元素

题目 法1&#xff1a;小根堆 最大的K个元素 > 小根堆&#xff08;类似上窄下宽的梯形&#xff09; 最小的K个元素 > 大根堆&#xff08;类似倒三角形&#xff09; 必须掌握&#xff01;&#xff01;&#xff01; class Solution {public int findKthLargest(int[] nu…

4.3 媒资管理模块 - Minio系统上传图片与视频

文章目录 一、上传图片1.1 需求分析1.2 数据模型1.2.1 media_files 媒资信息表 1.3 准备Minio环境1.3.1 桶环境1.3.2 连接Minio参数1.3.3 Minio配置类 1.4 接口定义1.4.1 上传图片接口请求参数1.4.2 上传图片接口返回值1.4.3 接口代码 1.5 MediaFilesMapper1.6 MediaFileServic…

解决log4j多个日志都写到一个文件

之前客户端程序由于Websockt包依赖的log4j&#xff0c;就用log4j写日志了&#xff0c;Web用的log4j2没毛病。用log4j的多个logger的日志都写到一个文件里了&#xff0c;查了很多资料都没解决。今天闲了解决一下。 最后好使的配置 # 设置日志根 log4j.rootLogger INFO,Except…

uni-app之HelloWorld实现

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…

选择排序(java)

选择排序 选择排序是默认前面都是已经排序好的&#xff0c;然后从后面 选择最小的放在前面排序好的的后面&#xff0c;首先第一轮循环的时候默认的排序好的为空&#xff0c;然后从后面选择最小的放到数组的第一个位置&#xff0c;第二轮循环的时候默认第个元素是已经 排序好的…

深度学习中的Dropout

1 Dropout概述 1.1 什么是Dropout 在2012年&#xff0c;Hinton在其论文《Improving neural networks by preventing co-adaptation of feature detectors》中提出Dropout。当一个复杂的前馈神经网络被训练在小的数据集时&#xff0c;容易造成过拟合。为了防止过拟合&#xff…

光耦继电器

光耦继电器(光电继电器) AQW282SX 282SZ 280SX 280SZ 284SX 284SZ 212S 212SX 21 2SZ 文章目录 光耦继电器(光电继电器)前言一、光耦继电器是什么二、光耦继电器的类型三、光电耦合器的应用总结前言 光耦继电器在工业控制、通讯、医疗设备、家电及汽车电子等领域得到广泛应…

基于鸢尾花数据集的逻辑回归分类实践

基于鸢尾花数据集的逻辑回归分类实践 重要知识点 逻辑回归 原理简介&#xff1a; Logistic回归虽然名字里带“回归”&#xff0c;但是它实际上是一种分类方法&#xff0c;主要用于两分类问题&#xff08;即输出只有两种&#xff0c;分别代表两个类别&#xff09;&#xff0c…

Flutter windows 环境配置

Flutter windows 环境配置 从零开始&#xff0c;演示flutter环境配置到启动项目&#xff0c;同时支持 vscode 和 android studio 目录 Flutter windows 环境配置一、环境配置1. Flutter SDK2. Android Studio3. JDK4. 拓展安装5. Visual Studio 2022二、项目创建和启动1. vsco…

Spark集群部署与架构

在大数据时代&#xff0c;处理海量数据需要分布式计算框架。Apache Spark作为一种强大的大数据处理工具&#xff0c;可以在集群中高效运行&#xff0c;处理数十TB甚至PB级别的数据。本文将介绍如何构建和管理Spark集群&#xff0c;以满足大规模数据处理的需求。 Spark集群架构…

小狐狸ChatGPT付费创作系统小程序端开发工具提示打开显示无法打开页面解决办法

最新版2.6.7版下载&#xff1a;https://download.csdn.net/download/mo3408/88656497 很多会员在上传小程序前端时经常出现首页无法打开的情况&#xff0c;错误提示无法打开该页面&#xff0c;不支持打开&#xff0c;这种问题其实就是权限问题&#xff0c;页面是通过调用web-v…

vue3(七)-基础入门之事件总线与动态组件

一、事件总线 事件总线使用场景&#xff1a; 两个兄弟组件之间的传参&#xff0c;或者两个没有关联的组件之间的传参 html &#xff1a;引入 publicmsg 与 acceptmsg 自定义组件 (自定义组件名称必须小写) <body><div id"app"><publicmsg></…