目录
B-小雷的神奇电脑
思路:先求出最小异或和,然后取反后就是最大同或和
void solve()
{
int n,m;
std::cin>>n>>m;
std::vector<int>a(n,0);
for(int i=0;i<n;i++)
std::cin>>a[i];
std::sort(a.begin(), a.end(),std::greater<>());
int res=INT_MAX;
for(int i=0;i<n-1;i++) res=std::min(res,a[i]^a[i+1]);
//std::cerr<<res<<'\n';
std::cout<<(1<<m)-1-res<<'\n';
}
C-岗位分配
思路:除去每个岗位至少要的人数剩余r人,分配到k个岗位或者空闲,转化为经典球盒模型,即r个相同球放到k+1个不同盒子,允许为空的方案数
方案数为
void solve()
{
int n,m;
std::cin>>n>>m;
std::vector<i64>a(n,0);
i64 r=0;
for(auto &x:a) std::cin>>x,r+=x;
std::cout<<binom::C(m-r+n,n)%mod<<'\n';
}
D-简单的素数
思路:签到题,判断是否为质数
void solve()
{
i64 x;
std::cin>>x;
auto check=[&](i64 n)->bool
{
for(int i=2;i<=n/i;i++)
if(n%i==0) return false;
return true;
};
std::cout<<(check(x)?"Yes\n":"No\n");
}
E-AND
思路:欧拉筛筛选出质数,二分找到第一个≥x的质数和最后一个≤y的质数可求出区间质数个数res,因为质数只有2为偶数,所以区间左端点包含2时,答案为res-2。如果区间左端点不包含2或者res==1时,答案为0
void solve()
{
int x,y;
std::cin>>x>>y;
//std::cout<<sz(pri)<<'\n';
int l1=0,l2=0,r1=sz(pri)-1,r2=sz(pri)-1,res1=0,res2=0;
while (l1<=r1)
{
int mid=l1+r1>>1;
if(pri[mid]>=x) r1=mid-1,res1=mid;
else l1=mid+1;
}
while (l2<=r2)
{
int mid=l2+r2>>1;
if(pri[mid]<=y) l2=mid+1,res2=mid;
else r2=mid-1;
}
int res=res2-res1+1;
std::cout<<res<<' ';
if(res==1||x>2) std::cout<<"0\n";
else std::cout<<res-2<<'\n';
}
F-小雷的算式
思路:按题意模拟即可
void solve()
{
std::string s;
std::cin>>s;
std::multiset<int>se;
std::string tmp="";
for(auto x:s)
{
if(std::isdigit(x)) tmp+=x;
else
{
se.insert(std::stoi(tmp));
tmp="";
}
}
if(tmp!="") se.insert(std::stoi(tmp));
std::priority_queue<int>q;
int ans=0;
for(auto x:se)
{
ans+=x;
q.push(x);
}
while (sz(q)!=1)
{
std::cout<<q.top()<<'+';
q.pop();
}
std::cout<<q.top()<<'\n';
std::cout<<ans<<'\n';
}
H-聪明且狡猾的恶魔
思路:博弈论海盗分金币问题,答案为x-(n-1)/2
void solve()
{
i64 x,n;
std::cin>>x>>n;
std::cout<<x-(n-1)/2<<'\n';
}
I-马拉松
思路:DFS处理子树大小
void solve()
{
int n,x,y;
std::cin>>n>>x>>y;
x--,y--;
std::vector<std::vector<int>>adj(n);
std::vector<i64>siz(n,1);
std::vector<int>vis(n,0);
for(int i=0;i<n-1;i++)
{
int u,v;
std::cin>>u>>v;
u--,v--;
adj[u].pb(v);
adj[v].pb(u);
}
auto dfs=[&](auto &&self ,int u,int fa=-1)->void
{
if(u==y) vis[u]=1;
for(auto v:adj[u])
{
if(v==fa) continue;
self(self,v,u);
siz[u]+=siz[v];
vis[u]|=vis[v];
}
};
dfs(dfs,x);
for(auto v:adj[x])
{
if(vis[v])
{
std::cout<<(siz[x]-siz[v])*siz[y]<<'\n';
return;
}
}
}