1.开干灯,二分法的题。
在遥远的巨神峰,居住着许多灯泡精灵。每个精灵都有自己独特的编号,从 1 到 n 。在这个王国,所有的灯泡一开始都是亮着的,它们的光芒把整个王国照亮。然而,灯泡精灵们决定进行一场神秘的仪式,每个精灵按以下规则翻转灯光状态。
仪式的规则如下:对于每个 i=1,2,…,n ,所有编号为 j 的灯泡精灵( j 能整除 i )都将被翻转状态,也就是说,如果灯泡精灵的灯光是亮的,就会变为暗的;相反,如果灯光是暗的,就会变为亮的。随着仪式的进行,灯光开始忽明忽暗
经过仪式后,灯泡精灵们希望有 k 盏灯泡依然亮着,他们需要找到满足这一条件的最小的 n ,使得最终仍有正好 k 个灯泡点亮。
输入描述 每个测试包含多个测试用例。
第一行包含测试用例的数量 t ( 1≤t≤2×105 )。
测试用例的描述如下。
每个测试用例的唯一一行包含一个整数 k ( 1≤k≤109 )。
可知,为奇数并且是完全平方数或者是因子只有三个的数编号的灯的状态会改变。所以现在的问题是找到第k个不是完全平方数的数字。这可以通过二分搜索n的值来完成,使得n−⌊√n⌋=k 或直接公式n=⌊k+√k+0.5⌋ 。 对于二分时间复杂度O(Tlogk)
由此可见二分可以用来解方程,一种数学方法思维。
代码如下。
include<bits/stdc++.h>
using namespace std;
//二分查找精细方程的根。
long long findmin(long long k){
long long l=k,r=1e18;
long long mid;
while(l<r){
mid=(l+r)/2;
//运用强制类型转化精细一下方程。
if(mid-(long long)sqrt((double)mid)>=k)
r=mid;
else if(mid-(long long)sqrt((double)mid)<k)
l=mid+1;
}
return l;
//返回的是l为什么不是r?
} int main(){ long long t;
cin>>t;
while(t--){
long long num;
cin>>num;
cout<<findmin(num)<<"\n";
}
return 0;
}