题解 集合
首先最终集合大小为 是容易 check 的
为 可以先均质因数分解然后从 1 到 n 扫描线删去 的质因子
这里只需要记录每个质因子的奇偶性就行
然后正解:
打表发现答案好像都和 差不多
尝试拆式子,先假设 是偶数
发现最坏情况是删个 2 再删个
是奇数的话把 删了可以变成偶数
所以答案的下界是
于是只需要 check 和 的情况了
- 对于「判断一个东西出现了奇数次还是偶数次」一类的问题:
若要判断的数较少可以考虑 bitset
若只需要知道存不存在为奇/偶的可以用异或 hash
于是 可以 check
可以check是否存在
剩下的就是 的情况了,因为达到了答案下界所以删 一定是合法的
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000010
#define fir first
#define sec second
#define pb push_back
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n;
namespace force{
ll fac[50][50], tem[50], ans, rec;
void divide(ll n, ll* div) {
ll m=n;
for (ll i=2; i*i<=n; ++i) if (m%i==0) {
do {m/=i; ++div[i];} while (m%i==0);
}
if (m>1) ++div[m];
}
void solve() {
for (int i=1; i<=n; ++i) divide(i, fac[i]);
//cout<<"div: "<<endl;
//for (int i=1; i<=n; ++i) {for (int j=1; j<=n; ++j) cout<<fac[i][j]<<' '; cout<<endl;}
for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) fac[i][j]+=fac[i-1][j];
//cout<<"fac: "<<endl;
//for (int i=1; i<=n; ++i) {for (int j=1; j<=n; ++j) cout<<fac[i][j]<<' '; cout<<endl;}
int lim=1<<n;
for (int s=1; s<lim; ++s) {
for (int j=1; j<=n; ++j) tem[j]=0;
for (int i=1; i<=n; ++i) if (s&(1<<(i-1))) {
for (int j=1; j<=n; ++j) tem[j]+=fac[i][j];
}
for (int j=1; j<=n; ++j) if (tem[j]&1) goto jump;
if (__builtin_popcount(s)>ans) {
ans=__builtin_popcount(s), rec=s;
//cout<<ans<<endl;
//cout<<"tem: "; for (int i=1; i<=n; ++i) cout<<tem[i]<<' '; cout<<endl;
}
jump: ;
}
cout<<ans<<endl;
for (int i=1; i<=n; ++i) if (rec&(1<<(i-1))) cout<<i<<' '; cout<<endl;
}
}
namespace task1{
bool tem[N], vis[N];
set<int> s;
vector<pair<ll, bool>> div[N];
void divide(ll n) {
ll m=n;
for (ll i=2; i*i<=n; ++i) if (m%i==0) {
pair<ll, bool> t={i, 0};
do {m/=i; t.sec^=1;} while (m%i==0);
div[n].pb(t);
}
if (m>1) div[n].pb({m, 1});
}
void solve() {
for (int i=1; i<=n; ++i) {
divide(i);
for (auto it:div[i])
if ((n-i+1)&1) {tem[it.fir]^=it.sec;}
}
for (int i=1; i<=n; ++i) if (tem[i]) goto jump;
cout<<n<<endl;
for (int i=1; i<=n; ++i) printf("%d ", i);
cout<<endl;
jump: ;
//for (int i=1; i<=n; ++i) cout<<tem[i]<<' '; cout<<endl;
for (int i=1; i<=n; ++i) if (tem[i]) vis[i]=1; //, cout<<i<<endl;
for (int i=2; i<=n; ++i) {
//cout<<"i: "<<i<<endl;
for (auto it:div[i]) {
tem[it.fir]^=it.sec;
if (tem[it.fir]) vis[it.fir]=1;
else vis[it.fir]=0;
}
//cout<<"s: "; for (auto it:s) cout<<it<<' '; cout<<endl;
if (!s.size()) {
cout<<n-1<<endl;
for (int j=1; j<=n; ++j) if (j!=i) printf("%d ", j);
cout<<endl;
exit(0);
}
}
}
}
namespace task{
bool npri[N];
int pri[N], low[N], lowp[N], lowc[N], pcnt;
ll val[N], h[N], hf[N], sum;
unordered_map<ll, int> mp;
ll divide(int n) {ll ans=0; for (int t=n; t>1; t/=lowp[t]) if (lowc[t]&1) ans^=val[low[t]]; return ans;}
void solve() {
random_device seed;
mt19937_64 rand(seed());
for (int i=2; i<=n; ++i) val[i]=rand();
for (int i=2; i<=n; ++i) {
if (!npri[i]) pri[++pcnt]=low[i]=lowp[i]=i, lowc[i]=1;
for (int j=1,x; j<=pcnt&&i*pri[j]<=n; ++j) {
npri[x=i*pri[j]]=1;
if (!(i%pri[j])) {
low[x]=low[i];
lowp[x]=lowp[i]*pri[j];
lowc[x]=lowc[i]+1;
break;
}
else low[x]=lowp[x]=pri[j], lowc[x]=1;
}
}
for (int i=2; i<=n; ++i) h[i]=divide(i);
for (int i=2; i<=n; ++i) mp[hf[i]=hf[i-1]^h[i]]=i;
for (int i=2; i<=n; ++i) sum^=hf[i];
if (!sum) {printf("%d\n", n); for (int i=1; i<=n; ++i) printf("%d ", i); printf("\n"); exit(0);}
for (int i=2; i<=n; ++i) if (!(sum^hf[i])) {
printf("%d\n", n-1);
for (int j=1; j<=n; ++j) if (j!=i) printf("%d ", j); printf("\n");
exit(0);
}
for (int i=2; i<=n; ++i) if (mp.find(sum^hf[i])!=mp.end()) {
printf("%d\n", n-2);
int t=mp[sum^hf[i]];
for (int j=1; j<=n; ++j) if (j!=i && j!=t) printf("%d ", j); printf("\n");
exit(0);
}
printf("%d\n", n-3);
for (int i=1; i<=n; ++i) if (i!=2 && i!=n/2 && i!=n) printf("%d ", n);
printf("\n");
}
}
signed main()
{
freopen("mountain.in", "r", stdin);
freopen("mountain.out", "w", stdout);
n=read();
// if (n<=20) force::solve();
// else task1::solve();
task::solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)