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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第十五节TypeScript 接口

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

编程规范:长函数的思考

在工作&#xff0c;我们应该都不想看到非常的长函数。对于一个运行5年左右的项目&#xff0c;极有可能出现这种情况。由于长函数的长、if/else嵌套&#xff0c;导致代码的可读性非常差&#xff0c;这对于项目的维护和开发带来了极大的困难。所以我们应该避免写长函数&#xff0…

OpenAI科学家Hyung Won Chung演讲精华版

文章目录 第一个观点&#xff1a;涌现第二个观点&#xff1a;如何扩大规模1、标记化2、嵌入3、计算4、评估&#xff08;损失函数&#xff09;5、反向传播 最近从Google跳槽到OpenAI的AI科学家 Hyung Won Chung 比较拗口&#xff0c;我就简称尚哥了 他最近做了一个技术演讲 …

智能化中的控制与自动化中的控制不同

智能化中的控制相对于自动化中的控制更加灵活、智能、综合和学习能力强。智能化控制系统能够根据实际情况进行自主决策和优化&#xff0c;适用范围更广&#xff0c;效果更好。 首先&#xff0c;智能化控制系统能够根据外部环境的变化和实时数据的反馈来自主调整和优化控制策略&…

java实现深度优先搜索 (DFS) 算法

度优先搜索&#xff08;Depth First Search&#xff0c;DFS&#xff09;算法是一种用于遍历或搜索图或树的算法。这种算法从一个节点开始&#xff0c;沿着一条路径尽可能深地搜索&#xff0c;直到遇到不能继续前进的节点时返回上一个节点&#xff0c;然后继续搜索其他路径。具体…

Mac 右键拷贝文件失效

问题&#xff1a;Mac 右键拷贝文件失效&#xff0c;有时候拷贝可以成功&#xff0c;有时候拷贝不成功 发现问题所在&#xff1a;开了百度翻译的划词&#xff0c; 解决&#xff1a;把划词关掉就好了&#xff0c;或者设置划词快捷键翻译就好了&#xff0c;反正就不要一划就翻译那…

案例167:基于微信小程序的校园失物招领小程序

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

三道C语言中常见的笔试题及答案(一)

题目一&#xff1a; 问题&#xff1a; 解释以下代码中的#define预处理指令的作用&#xff0c;并说明其优点和缺点。 #include <stdio.h> #define PI 3.14159 #define CALCULATE_AREA(r) (PI * r * r) int main() { double radius 5.0; double area CALCULATE_AREA(r…

线程的同步与互斥

抢票的例子 竞争过程 进程A被切走 进程B被切走 结论&#xff1a; 互斥 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); mutex: 指向要初始化的互斥锁的指针。attr: 用于设置互斥锁属性的指针&#xff0c;通常可以传入 NULL 以使用默认属性…

Node.js教程-express框架

概述 Express是基于Node.js平台(建立在Node.js内置的http模块上)&#xff0c;快速、开放、极简的Web开发框架。 中文官网 http://www.expressjs.com.cn/。 Github地址&#xff1a;https://github.com/orgs/expressjs。 Express核心特性&#xff1a; 可设置中间件来响应 HTTP…

智能优化算法应用:基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于法医调查算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.法医调查算法4.实验参数设定5.算法结果6.…

基于阿里云服务网格流量泳道的全链路流量管理(二):宽松模式流量泳道

作者&#xff1a;尹航 在前文基于阿里云服务网格流量泳道的全链路流量管理&#xff08;一&#xff09;&#xff1a;严格模式流量泳道中&#xff0c;我们介绍了使用服务网格 ASM 的严格模式流量泳道进行全链路灰度管理的使用场景。该模式对于应用程序无任何要求&#xff0c;只需…

4. java——多态(java巅峰设计,超越了C++的理解,取其精华,去其糟粕)

多态指的是同—个行为具有多个不同表现形式 。是指—个类实例(对象&#xff09;的相同方法在不同情形下具有 不同表现形式。封装和继承是多态的基础&#xff0c;也就是说&#xff0c;多态只是—种表现形式而已。一个对象&#xff0c;同一个方法不同形态&#xff0c;方法必须重…

Redis源码精读:准备工作

文章目录 前言拉取源码项目结构源码阅读技巧最后 前言 我是醉墨居士&#xff0c;未来的一段时间里面我准备写一些关于Redis源码的文章&#xff0c;来帮助大家深入浅出Redis&#xff0c;希望大家多多支持&#x1fae0; 拉取源码 git clone https://github.com/redis/redis项目…

大数据----基于sogou.500w.utf8数据的MapReduce编程

目录 一、前言二、准备数据三、编程实现3.1、统计出搜索过包含有“仙剑奇侠传”内容的UID及搜索关键字记录3.2、统计rank<3并且order>2的所有UID及数量3.3、上午7-9点之间&#xff0c;搜索过“赶集网”的用户UID3.4、通过Rank&#xff1a;点击排名 对数据进行排序 四、参…

爬虫响应cookie阿里系案例:某财经

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、响应cookie阿里系特点 cookie中一定有acw_sc__v2清除所有cookie刷新页面时&#xff0c;会自动debugger到设置cookie的文件…

YOLOv8改进 | 主干篇 | 利用SENetV2改进网络结构 (全网首发改进)

一、本文介绍 本文给大家带来的改进机制是SENetV2&#xff0c;其是2023.11月的最新机制(所以大家想要发论文的可以在上面下点功夫)&#xff0c;其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型&#xff0c;而是一个可以和现有的任何…

Spark集群部署与架构

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

微服务实战系列之Dubbo(上)

前言 随着一年一度冬至的到来&#xff0c;2023的步伐也将远去。而博主的系列文章&#xff0c;也将从今天起&#xff0c;越来越聚焦如何构建微服务“内核”上。前序系列文章几乎囊括了微服务的方方面面&#xff0c;无论使用什么框架、组件或工具&#xff0c;皆可拿来用之。 那么…

数据处理系列课程 02:数据处理的科学性之初识NumPy

前面我们才提到数据处理是一件非常重要的事情&#xff0c;数据处理的是否得当直接关系到最终的成果&#xff0c;所以针对数据要做缺失值处理、离群点处理、重复值处理、噪声处理、规范化处理、离散化处理、稀疏化处理等处理&#xff0c;这些处理操作的基础都是建立在数学的基础…