2019杭电多校第四场
AND Minimum Spanning Tree
求一个完全图的最小生成树,定义边(u,v)的权值为u&v。
n为1e6,暴力肯定求不了,找规律:
发现任何偶数&1的时候都为0,奇数的情况发现只要和相反数按位与就为0,但是要满足字典序最小,所以只要保留最低位的1即可。
Minimal Power of Prime
1s,50000次询问,1e18分解质因数,求最小的因数的幂。
关注题目,因为只要求最小的幂,并没有要求全部分解出来。
经过观察,给出的数的素因子越大,其幂越小。先用以内的素数试着将分解,不妨将剩下的部分记为,可知的因子一定大于。想要求幂最小的情况,不妨先考虑幂最大的情况,发现当时,有最多的幂。又M<1e18,故。因此可以分解为四种情况,将之前分解的最小值与出现这几种情况之一时的值比较一下即可。
贴上队友的代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
//#include<time.h>
#define ll long long
using namespace std;
ll pri[1020]={2,3,5,7,11,...,8093,8101,8111};
ll cnt=1000;
ll T,n;
int main(){
//clock_t start = clock();
//srand(time(NULL));
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
ll _n=n;
ll mn=100,tmp;
for(ll i=1;i<=600;i++){
tmp=0;
while(!(_n%pri[i])){
tmp++;
_n/=pri[i];
}
if(tmp){
mn=min(mn,tmp);
if(mn==1) break;
}
}
if(mn==1||_n==1){
printf("%lld\n",mn);
continue;
}
ll s4=pow(_n+0.3,1.0/4)+0.3;
ll s3=pow(_n+0.3,1.0/3)+0.3;
ll s2=sqrt(_n)+0.3;
if(s4*s4*s4*s4==_n){
mn=min(mn,4);
}
else if(s2*s2==_n){
mn=min(mn,2);
}
else if(s3*s3*s3==_n){
mn=min(mn,3);
}
else{
mn=min(mn,1);
}
printf("%lld\n",mn);
}
//clock_t ends = clock();
//cout <<"Running Time : "<<(double)(ends - start)/ CLOCKS_PER_SEC << endl;
return 0;
}
浙公网安备 33010602011771号