位运算 数学优化 1891 B. Deja Vu

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

void solve()
{
	int n;
	cin>>n;
	
	int q;
	cin>>q;
	
	vector<long long> a(n);
	vector<int> x(q);
	
	for(int i=0;i<n;i++)	cin>>a[i];
	for(int i=0;i<q;i++)	cin>>x[i];
	
	for(int i=0;i<q;i++)
		for(int j=0;j<n;j++)
			if(a[j]%(1<<x[i])==0)
				a[j]+=1<<(x[i]-1);
	
	for(int i=0;i<n;i++)	
		cout<<a[i]<<" ";
	cout<<endl;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t;
	cin>>t;
	
	while(t--)
		solve();
	
	return 0;
}

本来以为秒了,结果在第三个测试点超时了。

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

void solve()
{
	int n,q;
	cin>>n>>q;
	
	vector<long long> a(n);
	for(int i=0;i<n;i++)	cin>>a[i];
	
	int m=30+10;
	while(q--)
	{
		int x;
		cin>>x;
		if(x<m)
		{
			m=x;
			for(int i=0;i<n;i++)
				if(a[i]%(1<<m)==0)
					a[i]+=1<<(m-1);
		}
	}
	
	for(auto e:a)
		cout<<e<<" ";
	cout<<endl;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t;
	cin>>t;
	
	while(t--)
		solve();
	
	return 0;
}

需要考虑一个优化,不然肯定超时

假设原来有一个数字a[i]可以整除数字 2 x [ j ] 2^{x[j]} 2x[j],那么a[i]更新之后肯定不可以整除 2 x [ j ] 2^{x[j]} 2x[j],举一个例子i,比如说8本来可以整除4,现在加上2之后就不能整除4

归纳推理可知,被 2 x [ j ] 2^{x[j]} 2x[j]更新之后,就只能被比 2 x [ j ] 2^{x[j]} 2x[j]更小的数字更新,所以最多30次操作,时间复杂度是 30 ⋅ n 30\cdot n 30⋅n

1 < < n 1<<n 1<<n表示 2 n 2^n 2n
n < < 1 = 2 ⋅ n n<<1=2\cdot n n<<1=2⋅n

数据比较大,a数组需要开long long

相关推荐
Tisfy2 分钟前
LeetCode 1523.在区间范围内统计奇数数目:两种方法O(1)算
算法·leetcode·题解
癫狂的兔子20 分钟前
【Python】【机器学习】线性回归
算法·回归·线性回归
野犬寒鸦21 分钟前
ArrayList扩容机制深度解析(附时序图详细讲解)
java·服务器·数据结构·数据库·windows·后端
tankeven1 小时前
HJ92 在字符串中找出连续最长的数字串
c++·算法
小雨中_1 小时前
3.1 RLHF:基于人类反馈的强化学习
人工智能·python·深度学习·算法·动态规划
relis1 小时前
从 dma-buf 到 tensor parallel:跨越领域的零拷贝模式
算法
一条大祥脚1 小时前
Manacher/马拉车算法
算法
phoenix@Capricornus1 小时前
初等数学中点到直线的距离
人工智能·算法·机器学习
田里的水稻2 小时前
FA_规划和控制(PC)-快速探索随机树(RRT)
人工智能·算法·数学建模·机器人·自动驾驶
jaysee-sjc2 小时前
十三、Java入门进阶:异常、泛型、集合与 Stream 流
java·开发语言·算法