第一题:Aaronson
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<math.h>
using namespace std;
typedef long long LL;
int pow(int a,int n){
int ans = 1;
while(n){
if(n&1) ans = ans*a;
a = a*a;
n>>=1;
}
return ans;
}
int main()
{
int tcase;
scanf("%d",&tcase);
while(tcase--){
int n,m;
scanf("%d%d",&n,&m);
int k = n;
int ans = 0,cnt = 0;
while(n){
cnt++;
if(n%2==1) ans++;
n/=2;
}
if(cnt<=m+1) printf("%d\n",ans);
else {
int cnt = 0;
int t = pow(2,m);
//printf("%d\n",k);
while(k&&t){
//printf("%d %d\n",k,t);
cnt+=k/t;
k = k - k/t*t;
t/=2;
}
printf("%d\n",cnt);
}
}
return 0;
}
第二题:Bellovin
解题思路:利用nlogn求LIS的方法即可,每次用二分找到的ai的位置,就是bi的值(因为保证字典序最小)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100005;
int n,a[maxn],d[maxn],ans[maxn];
int binsearch(int l,int r,int key)
{
int mid;
while(l <= r)
{
mid = (l + r) >> 1;
if(d[mid] == key) return mid;
else if(d[mid] < key) l = mid + 1;
else r = mid - 1;
}
return l;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
int len = 0;
for(int i = 1; i <= n; i++)
{
int tmp = binsearch(1,len,a[i]);
ans[i] = tmp;
d[tmp] = a[i];
if(tmp > len) len = tmp;
}
for(int i = 1; i < n; i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}
第四题: Dertouzos
解题思路:我们先分解d的因子,假设最大的为p,那么我们就需要找到一个最大的素数x,使得x*p<=d,否则求出的数最大的因子不可能是d,而是x*p,我们以n=20,d=8为例,最大的因子p=4,那么我们找到的最大素数只能是2,所以得出的结果是1。在寻找最大素数时,可以先打表,再用二分去求解。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn = 100005;
int p[maxn],cnt;
LL prime[maxn];
void init()
{
p[1] = 1;
cnt = 0;
for(LL i = 2; i <= 100000; i++)
{
if(!p[i])
{
prime[++cnt] = i;
for(LL j= i * i; j <= 100000; j += i)
p[j] = 1;
}
}
}
LL qpow(int a,int b,int r)
{
LL ans=1,buff=a;
while(b)
{
if(b&1)
ans=(ans*buff)%r;
buff=(buff*buff)%r;
b>>=1;
}
return ans;
}
bool Miller_Rabbin(int n,int a)
{
int r=0,s=n-1,j;
if(!(n%a))
return false;
while(!(s&1))
{
s>>=1;
r++;
}
LL k=qpow(a,s,n);
if(k==1)
return true;
for(j=0;j<r;j++,k=k*k%n)
if(k==n-1)
return true;
return false;
}
bool IsPrime(int n)
{
int tab[5]={2,3,5,7};
for(int i=0;i<4;i++)
{
if(n==tab[i])
return true;
if(!Miller_Rabbin(n,tab[i]))
return false;
}
return true;
}
int main()
{
int t;
LL n,d;
scanf("%d",&t);
init();
while(t--)
{
scanf("%lld%lld",&n,&d);
LL m = 1;
if(IsPrime(d) == false)
{
for(int i = 2; i * i <= d; i++)
if(d % i == 0)
{
m = max(m,d / i);
break;
}
}
int l = 1,r = cnt,mid,ans = 0;
while(l <= r)
{
mid = (l + r) >> 1;
if(prime[mid] * d < n && prime[mid] * m <= d)
{
ans = mid;
l = mid + 1;
}
else r = mid - 1;
}
printf("%d\n",ans);
}
return 0;
}