2022.9.14 - 9.20的CF做题总结【标签: 二进制 / constructive algorithms 难度: 1200~1400】

从博客园转攻CSDN

第一篇就总结下九月里做过的题吧

战况预览

在这里插入图片描述

9.19


C. Array Elimination

https://codeforces.com/problemset/problem/1602/C

类型:二进制 难度:1300

二进制不熟悉的小伙伴可以多做些之类的题, 自然就会了~

题意
n个数,要求找出所有的k,使得操作后所有数都为0
操作: 每次选择k个数,计算x=ai1 & ai2 & … & aik 然后其中(ai1、ai2 … aik)每个数都减去x

题解
补充: 只有1&1=1, 其它结果都是0
取几个数哪一位二进制都是1, 然后他们一起&, 就能消除二进制的这个1
为了保证每个二进制的1都能消除, 所以k应该取每一位1的数目的公因数。也就是找出最大公因数(gcd), 输出gcd的所有因数

例: 13和7
13 - 1101
7 - 111
13和7&的结果就是 5(101),
13和7减去5就消去了倒数第一位和倒数第三位的1

代码

#include <bits/stdc++.h>
#include <stack>
#include <queue>
typedef long long LL;

using namespace std;
const int N = 2e5+10;

int a[N], res[40];

void f(int x)
{
	for(int i = 32; i >=0; i --)//i=20也没有问题,因为n<2e5
	{
		res[i] += ((x>>i)&1);
	}
}
int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		memset(res, 0, sizeof res);
		int n;
		cin >> n;
		for(int i = 0; i < n; i ++)
		{
			cin >> a[i];
			f(a[i]);
		}
		
		int ans = 0;
		for(int i = 0; i <= 32; i ++)
		{
			if(ans == 0 && res[i]!=0) ans = res[i];
			else if(res[i]!=0) ans = __gcd(ans, res[i]);//ans是最大公约数
		}
	
		for(int i = 1; i <= n && i<=ans; i ++)//输出ans的所有因数
			if(ans%i==0)
				cout << i << ' ';
		cout <<endl;
	}
    return 0;
}

9.18

B. And It’s Non-Zero

https://codeforces.com/problemset/problem/1615/B

类型: 二进制,前缀和 难度:1300

题意
给出l, r ,要求删去区间[l, r] 里最少的数使得所有数&后不等于0

题解
此题不难想到找出二进制哪一位1的个数最大, 并用n减去这个数就行了
难点在于暴力求解 1e4*2e5会超时, lowbit优化也不可以。想办法去优化多次计算的部分,可以考虑前缀和,因为数都是1~2e5里连着数

代码

#include <bits/stdc++.h>

typedef long long LL;

using namespace std;
const int N = 2e5+10;

map<int,int> mp[N];

void init()
{
	for(int j = 0; j < 21; j ++) mp[0][j]=0;
	
	for(int i = 1; i < N ; i ++)
		for(int j = 0; j < 21; j ++)
			mp[i][j] = (i>>j&1)+mp[i-1][j];
}

int main()
{
	init();
	
    int t;
    cin >> t;
	int n = 0;
	int l, r;
    while(t --)
    {
    	int res=0;
    	cin >> l >> r;
    	
    	for(int i = 0; i < 21; i ++)
    		res = max(res, mp[r][i]-mp[l-1][i]);
    	cout<<r-l+1-res<<'\n';
    }
      
    return 0;
}

C. LIS or Reverse LIS?

https://codeforces.com/problemset/problem/1682/C

类型:数字构造,排序 难度:1400 不难

题意
lis()表示序列严格单增的数字个数,不含相等
要求根据已知n个数排列后构造出min(lis(a1,a2,an), lis(an,a2,a1) )的最大值

题解
要求就是构造出山峰,求山顶到两边最近山底的最大值,把序列排序后,从前往后遍历,出现过小于等于两次的数(山顶左边放一个,山顶右边放一个)都可以计入来构造山,最后偶数 = 总数/2 奇数 =(总数+1)/ 2

代码

#include <bits/stdc++.h>
typedef long long LL;

using namespace std;
const int N = 2e5+10;

int a[N];

int main()
{
    int m;
    cin >> m;
    while(m --){
       int n, s=0;
       cin >> n;
       for(int i = 0; i < n; i ++)	cin >> a[i];
       
       sort(a, a+n);//感觉不排序也可~
       map<int,int> st;
       for(int i = 0; i < n; i ++)
       {
       		if(st[a[i]]<=1) s++;
       		st[a[i]]++;
       }
       cout<<(s+1)/2<<'\n';
    }
    return 0;
}

9.14

C. Mocha and Hiking

https://codeforces.com/problemset/problem/1559/C

类型: 构造图 难度:1200 此题不难

题意
有n+1个点, 2n-1条路, 其中有n-1条路是从i到i+1
另外n条路根据输入, 在序列 a1, a2… an 中, ai =0是从 i 到n+1有一条路, =1是从n+1到 i 有一条路
要求连接1到n+1个点, 且每个点只用一次

题解
1~n都是连接的, 所以此题的关键是如何将n+1插入进来, 共有3种方式

1.插入末尾
2.插入开头
3.插入中间, 满足ai-1=0, ai=1即可
代码

#include <iostream>
typedef long long LL;

using namespace std;
const int N = 1e5+10;

bool a[N];
// If ai=1,  n+1 to village i.
int main()
{
    int m;
    cin >> m;
    while(m --){
       int n;
       cin >> n;
       for(int i = 0; i < n; i ++)	cin >> a[i];
       
       if(a[n-1] == 0)
       {
       		for(int i = 1; i <= n+1; i ++) cout << i << ' ';
       }
       else if(a[0]==1)
       {
       		cout << n+1<< ' ';
       		for(int i = 1; i <= n; i ++) cout << i << ' ';
       }
       else
       {
       		int f = 0;
	       	for(int i = 1; i < n; i ++)
	       	{
	       		if(a[i]==1 && a[i-1]==0 )	f=i;
	       	}
       		if(f) 
       		{
       			for(int i = 1; i <= f; i ++) cout << i << ' ';
       			cout << n+1 << ' ';
       			for(int i = f+1; i <= n; i ++) cout << i << ' ';
       		}
       		else puts("-1");
       }
       cout << '\n';
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: com.ex.guidqq.apk tx9.20 是一个应用程序的名称,可能是一个基于Android系统的手机应用。这个应用程序名称中的"com.ex.guidqq"可能代表着应用程序的开发者或公司名称,而"tx9.20"可能代表着应用程序的版本号。 根据 "guidqq" 这个词,我们可以猜测这个应用程序可能是和导航或者路线指引相关的。可能它提供了导航服务、地图功能或者是提供了路径规划、导航引导等功能。 至于应用程序版本号"tx9.20",通常版本号会随着功能的更新和优化而逐渐提升,不同的版本号可能代表着应用程序的不同改进和更新。"tx9.20"这个版本号可能是应用程序的第9个版本的20号更新。 总结来说,"com.ex.guidqq.apk tx9.20" 是一个可能是导航或路线指引相关的手机应用程序的名称,版本号为"tx9.20",可能是该应用程序的第九个版本的20号更新。 ### 回答2: com.ex.guidqq.apk tx9.20是一个APK文件的名称,具体是指一个名为“com.ex.guidqq”的应用程序文件,其版本为“tx9.20”。 APK是Android应用程序包的文件格式,用于在Android操作系统上安装和运行应用程序。这个特定的APK文件可能是一个类似于QQ的聊天应用程序。 "com.ex.guidqq"可能是该应用程序的包名,作为在Android平台上唯一标识该应用程序的标识符。 版本号"tx9.20"表示应用程序的版本,一般在每次更新应用程序时会更新版本号。通过版本号,可以知道该APK文件是应用程序的第9.20个版本。 综上所述,com.ex.guidqq.apk tx9.20是一个名为“com.ex.guidqq”的安卓应用程序文件,版本号为“tx9.20”,可能是一个聊天应用程序的第9.20个版本。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值