Educational Codeforces Round 142 E. Divisors and Table
链接:https://codeforces.com/problemset/problem/1792/E
题意:给定n * n乘法表,第a[ i ] [ j ] = i * j,给定m=m1 * m2,求m的所有因子中出现在表中的最小行的xor和。
n<=1e9,m1,m2<=1e9.
分析:对于m = 1e18,最多可表示为15个素数相乘,故最多有2^15-1个因子,数量级在4e4左右。求最小行,即为求最大列,即为求某个数可以分解r*c且c<=n,c尽量大。
考虑暴力做法,枚举每个因子的所有因子,找到最大的列,显然复杂度过大。再观察发现子问题包含最优解,一个数x的最大的c要不然是x,要不然是x的因子,那么对于其所有x/p的因子包含最优解,故可考虑递推。
f[x] 表示x所能表示的最大列数c,则f[x]=max(x,f[x/p1],f[x/p2],,,).这样做复杂度为最坏为T * 2^15 * log(m)。
代码:
//参考了网上大佬的代码(忘了是谁的了,,)
#include<bits/stdc++.h>
#define int long long
using namespace std;
map<int,int> mp;
int b[200100],f[200100],p[200100],poww[200100];
void dcp(int x){
for(int i=2;i*i<=x;i++){
while(x%i==0){
x/=i;
mp[i]++;
}
}
if(x>1) mp[x]++;
}
void dfs(int cur,int val,int cnt1,int &cnt2){
if(cur>cnt1){
b[++cnt2]=val;
return;
}
for(int i=0;i<=poww[cur];i++){
dfs(cur+1,val,cnt1,cnt2);
val*=p[cur];
}
}
void solve(){
int n;cin>>n;mp.clear();
int m1,m2;cin>>m1>>m2;
int ans=0,anss=0;
dcp(m1);dcp(m2);
int cnt1=0,cnt2=0;
for(auto it:mp){
cnt1++;
p[cnt1]=it.first;
poww[cnt1]=it.second;
}
dfs(1,1,cnt1,cnt2);
sort(b+1,b+cnt2+1);
for(int i=1;i<=cnt2;i++){
if(b[i]<=n) f[i]=b[i];
else f[i]=0;
for(int j=1;j<=cnt1;j++){
if(b[i]%p[j]==0){
f[i]=max(f[i],f[lower_bound(b+1,b+cnt2+1,b[i]/p[j])-b]);
}
}
int t=b[i]/f[i];
if(f[i]!=0&&t<=n){
ans++;
anss^=t;
}
}
cout<<ans<<" "<<anss<<endl;
}
signed main(){
int T;cin>>T;
while(T--) solve();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)