二分答案套路题,其中check用容斥瞎搞即可
代码:
#include<bits/stdc++.h>
namespace my_std
{
using namespace std;
#define int long long
#define R register
#define rep(i,a,b) for (R int i=(a);i<=(b);i++)
#define drep(i,a,b) for (R int i=(a);i>=(b);i--)
#define go(u) for (R int i=head[(u)];i;i=e[i].nxt)
#define pf printf
#define writeln(x) write(x),putchar('
')
#define writesp(x) write(x),putchar(' ')
#define mem(x,v) memset(x,v,sizeof(x))
typedef long long ll;
const int INF=1e12;
inline int read()
{
int sum=0,f=1;
char c=0;
while (!isdigit(c))
{
if (c=='-') f=-1;
c=getchar();
}
while (isdigit(c))
{
sum=(sum<<1)+(sum<<3)+(c^48);
c=getchar();
}
return sum*f;
}
void write(int k)
{
if (k<0) putchar('-'),k=-k;
if (k>=10) write(k/10);
putchar(k%10+'0');
}
bool bet(int bot,int x,int top)
{
return x>=bot&&x<=top;
}
}
using namespace my_std;
namespace ka_chang
{
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
}
using namespace ka_chang;
const int N=100010;
int n,k,a[N];
int gcd(int x,int y)
{
if (y==0) return x;
return gcd(y,x%y);
}
#define lcm(a,b) (a*b/gcd(a,b))
inline int get_sum(int mid)
{
int res=0,cnt,tmp;
rep(s,0,(1<<n)-1)
{
cnt=0,tmp=1;
rep(i,1,n) if (s&(1<<(i-1)))
{
tmp=lcm(tmp,a[i]);
cnt++;
}
if (cnt)
{
if (cnt&1) res+=mid/tmp;
else res-=mid/tmp;
}
}
return res;
}
signed main()
{
n=read(),k=read();
rep(i,1,n) a[i]=read();
int l=1,r=INF;
while (l<r)
{
int mid=(l+r)>>1;
if (get_sum(mid)>=k) r=mid;
else l=mid+1;
}
writeln(r);
}
(我是全队跑得最慢的,我也不知道为什么)
update : 我还是把容斥的过程写一下吧:
容斥遵循最基本的原则:奇加偶减
然后在 get_sum 函数里, s 枚举的是一个集合,代表 a 数组有没有被选中
再把集合中的数的最小公倍数求出即可
cnt 是集合 s 中的元素个数,即 popcount ,可以用 lowbit 预处理
最后奇加偶减即可