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

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.hqwc.cn/news/298197.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx快速入门:实现企业安全防护|nginx部署https,ssl证书(七)

0. 引言 之前我们讲到nginx的一大核心作用就是实现企业安全防护&#xff0c;而实现安全防护的原理就是通过部署https证书&#xff0c;以此实现参数加密访问&#xff0c;从而加强企业网站的安全能力。 nginx作为各类服务的统一入口&#xff0c;只需要在入口处部署一个证书&…

详解Vue3中的插槽(slot)

本文主要介绍Vue3中的插槽&#xff08;slot&#xff09;。 目录 一、在普通写法中使用插槽&#xff08;slot&#xff09;作用域插槽默认插槽 二、在setup写法中使用插槽&#xff1a;注意事项 在Vue3中&#xff0c;插槽&#xff08;slot&#xff09;是一种用于在父组件中向子组件…

Leetcode162. 寻找峰值

Every day a Leetcode 题目来源&#xff1a;162. 寻找峰值 解法1&#xff1a;STL 代码&#xff1a; class Solution { public:int findPeakElement(vector<int>& nums) {return max_element(nums.begin(), nums.end()) - nums.begin();} };复杂度分析&#xff1…

【SD】差异值 生成 同一人物 制作 表情包 【1】

说明&#xff1a;只对AI生成的人物&#xff0c;效果稳定。 Reference差异值 生成表情 首先生成一张图片。 测试命令&#xff1a;1 man,chibi,full body, 模型&#xff1a;envyclarityxl02_v10.safetensors [f6c13197db] 种子&#xff1a;2704867166 》》测试命令&#xff1a…

基于包围盒算法的三维点云数据压缩和曲面重建matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 包围盒构建 4.2 点云压缩 4.3 曲面重建 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...........................................…

【附三菱 MX OPC Server 6.04的安装包】MX-OPC下载以及用GX Works2和组态王进行仿真连接

使用MX-OPC来完成三菱和组态王的仿真连接。 文章目录 目录 文章目录 软件下载 1.OPC设置 2.GX Works 2 设置 3.GX Works 2 和OPC 连接测试 4.和组态王进行仿真连接 5.安装OPC后&#xff0c;GX Works2 无法打开 提示堆栈不足 6.收尾&#xff08;组态王变量的删除&#xff0…

Python - 深夜数据结构与算法之 Graph

目录 一.引言 二.图的简介 1.Graph 图 2.Undirected graph 无向图 3.Directed Graph 有向图 4.DFS / BFS 遍历 三.经典算法实战 1.Num-Islands [200] 2.Land-Perimeter [463] 3.Largest-Island [827] 四.总结 一.引言 Graph 无论是应用还是算法题目在日常生活中比较…

YOLOv7(目标检测)入门教程详解---检测,推理,训练

目录 一.前言 二.yolov7源码下载 三.detect&#xff08;检测&#xff09; 四.Train&#xff08;训练&#xff09; 数据准备&#xff1a; labellmg: 配置训练的相关文件 配置数据集文件 正式训练&#xff1a; 推理&#xff1a; 推理效果&#xff1a; 五.总结 一.前言 …

【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)

目录 一、C/C内存分布二、new和delete的使用方式2.1 C语言内存管理2.2 C内存管理2.2.1 new和delete操作内置类型2.2.2 new和delete操作自定义类型 三、new和delete的底层原理3.1 operator new与operator delete函数3.2 原理总结3.2.1 内置类型3.2.2 自定义类型 四、定位new表达…

docker笔记3-dockerfile定制镜像

dockerfile的组成 1.基础镜像信息&#xff0c;指定发行版本 FROM centos 2.制作镜像操作指令 RUN yum install openssh-server -y 3.容器启动指令执行 CMD [/bin/bash] dockerfile常用指令 指令 含义FROM指定基础镜像MAINTAINER指定维护人信息&#xff0c;可省略RUN基于基础…

靠谱免费的MAC苹果电脑杀毒软件CleanMyMac X2024

您是否曾经为Mac电脑的性能下降、存储空间不足而烦恼&#xff1f;是否希望有一个简单而高效的解决方案来优化您的Mac系统&#xff1f;那么&#xff0c;我向您介绍一款非常出色的工具&#xff1a;CleanMyMac X。它能够轻松处理这些问题&#xff0c;并让您的Mac恢复到最佳状态。 …

Unity 贝塞尔曲线工具获取运动轨迹

Unity 贝塞尔曲线工具获取运动轨迹 一、介绍贝塞尔曲线二、Unity中贝塞尔曲线工具介绍1.创建一个空物体挂在上BezierSpline.cs脚本组件2.由上图可知刚创建出来的有两个点和两个手柄组成3.我们可修改其坐标看下效果4.这样我们就可以获得这两个点之间的指定数量的点来作为某个物体…