2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest
目录
Contest Info
Solved | A | B | C | D | E | F | G | H | I | J | K | L |
---|---|---|---|---|---|---|---|---|---|---|---|---|
9 / 12 | O | O | O | - | O | - | Ø | Ø | O | - | O | O |
- O 在比赛中通过
- Ø 赛后通过
- ! 尝试了但是失败了
- - 没有尝试
Solutions
A. Auxiliary Project
简单dp即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/11 13:13:46
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e6 + 5;
const int mp[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
const int val[] = {-1, -1, 1, 7, 4, 5, 9, 8, -1, -1, -1};
int n;
int dp[N];
void run() {
freopen("auxiliary.in", "r", stdin);
freopen("auxiliary.out", "w", stdout);
cin >> n;
memset(dp, -1, sizeof(dp));
dp[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 10; j++) if (val[j] != -1 && i >= j && dp[i - j] != -1) {
dp[i] = max(dp[i], dp[i - j] + val[j]);
}
}
cout << dp[n] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
B. Boolean Satisfiability
开心签到。
Code
#include<cstdio>
#include<cstring>
using namespace std;
#define TM "boolean"
char buf[1007];
int chs[57][2];
int main() {
#ifndef LOCAL
freopen(TM".in", "r", stdin);
freopen(TM".out", "w", stdout);
#endif
scanf("%s", buf);
int l=strlen(buf);
memset(chs,0,sizeof chs);
int qf=false;
for(int i=0; i<l; i++) {
switch(buf[i]) {
case '~':
qf=true;
break;
case 'a' ... 'z':
chs[buf[i]-'a'][qf]=1;
qf=false;
break;
case 'A' ... 'Z':
chs[buf[i]-'A'+26][qf]=1;
qf=false;
break;
}
}
long long ans=1;
bool ok=false;
for(int i=0; i<52; i++) {
if(chs[i][0]&&chs[i][1]) ok=true;
}
if(!ok) {
for(int i=0; i<52; i++) {
if(chs[i][0] || chs[i][1])
ans*=2;
}
ans--;
} else {
for(int i=0; i<52; i++) {
if(chs[i][0]||chs[i][1]) {
ans*=2;
}
}
}
printf("%lld\n", ans);
return 0;
}
C. Consonant Fencity
因为不同字符数量很少,故直接状压枚举即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/11 14:53:04
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
const int ban[] = {0, 'e' - 'a', 'i' - 'a', 'o' - 'a', 'u' - 'a', 'w' - 'a', 'y' - 'a'};
string str;
int cnt[26], mp[26], mp2[26], change[26];
int a[26][26];
bool ok(int c) {
for (int i = 0; i < 7; i++) {
if (c == ban[i]) {
return false;
}
}
return true;
}
void run() {
freopen("consonant.in", "r", stdin);
freopen("consonant.out", "w", stdout);
cin >> str;
int n = str.length();
for (int i = 0; i < n; i++) {
if (ok(str[i] - 'a')) {
++cnt[str[i] - 'a'];
}
}
int tot = 0;
for (int i = 0; i < 26; i++) {
if (cnt[i]) {
mp[i] = tot;
mp2[tot] = i;
++tot;
}
}
if (tot == 0) {
cout << str << '\n';
return;
}
for (int i = 0; i < n; i++) {
if (i + 1 < n) {
if (ok(str[i] - 'a') && ok(str[i + 1] - 'a')) {
++a[mp[str[i] - 'a']][mp[str[i + 1] - 'a']];
++a[mp[str[i + 1] - 'a']][mp[str[i] - 'a']];
}
}
}
//for (int i = 0; i < tot; i++) {
//for (int j = 0; j < tot; j++) {
//cout << a[i][j] << ' ';
//} cout << '\n';
//cout << mp2[i] << '\n';
//}
int ans = 0;
for (int sta = 0; sta < 1 << (tot - 1); sta++) {
int res = 0;
for (int i = 0; i < tot - 1; i++) {
if (sta >> i & 1) {
for (int j = 0; j < tot; j++) {
if (!(sta >> j & 1)) {
res += a[i][j];
}
}
}
}
if (res > ans) {
ans = res;
memset(change, 0, sizeof(change));
for (int i = 0; i < tot; i++) {
if (sta >> i & 1) {
change[mp2[i]] = 1;
}
}
}
}
for (int i = 0; i < n; i++) {
if (change[str[i] - 'a']) {
str[i] = str[i] - 'a' + 'A';
}
}
cout << str << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
E. Equal Numbers
显然最后每个数只能都变为他们的\(lcm\)或者变到某一个数上面去。
那么对这两种情况都处理一下取最小值即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/11 15:57:13
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 3e5 + 5, MAX = 1e6 + 5;
int n;
int cnt[MAX];
struct node {
int c, v;
bool operator < (const node& A)const {
return c > A.c;
}
};
int ans1[MAX], ans2[MAX], to[MAX];
void solve1(int* ans) {
int k = n;
priority_queue <node> q;
for (int i = 1; i < MAX; i++) if (cnt[i]) {
q.push(node {cnt[i], i});
}
int cur = 0;
while (!q.empty()) {
node now = q.top(); q.pop();
if (k < now.c) break;
if (to[now.v] == now.v) continue;
cur += now.c;
--ans[cur];
k -= now.c;
}
}
void solve2(int* ans) {
int k = n;
priority_queue <node> q;
for (int i = 1; i < MAX; i++) if (cnt[i]) {
q.push(node {cnt[i], i});
}
int cur = 0;
while (!q.empty()) {
node now = q.top(); q.pop();
if (k < now.c) break;
cur += now.c;
if (cur != now.c) --ans[cur];
k -= now.c;
}
}
void run() {
freopen("equal.in", "r", stdin);
freopen("equal.out", "w", stdout);
cin >> n;
for (int i = 1; i <= n; i++) {
int x; cin >> x;
++cnt[x];
}
int tot = 0;
for (int i = 1; i < MAX; i++) if (cnt[i]) {
++tot;
for (int j = i; j < MAX; j += i) {
if (cnt[j]) {
to[i] = j;
}
}
}
solve1(ans1), solve2(ans2);
ans1[0] += tot, ans2[0] += tot;
for (int i = 1; i <= n; i++) {
ans1[i] += ans1[i - 1];
ans2[i] += ans2[i - 1];
}
for (int i = 0; i <= n; i++) {
int ans = min(ans1[i], ans2[i]);
cout << ans << " \n"[i == n];
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
G. Grand Test
题意:
给定\(n\)点\(m\)条边的有向图,现在要找到起点\(S\)和终点\(T\),并且满足\(S\rightarrow T\)存在三条除开起点终点之外的点不重复的路径,并且要输出路径。
思路:
画图即可发现,若满足题中条件,一定具有“由两个环拼接起来”的特征,即两个环共享一部分,画个图就比较显然了。
那么找环的问题我们可以在\(dfs\)树或者\(bfs\)树上解决。
对于每条返祖边\((u,v)\),暴力给树上\(u\rightarrow v\)的路径染色。若某条边有两种颜色那么说明存在两个环重合,直接扣出来暴力\(dfs\)找路径即可。
细节见代码:
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/12 15:31:13
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int n, m;
vector <pii> G[N], edges;
vector <int> nG[N];
pii color[N], f[N];
int vis[N], dfn, c1, c2;
bool flag;
int paint(int x, int c) {
if (color[x].fi == -1) {
color[x].fi = c;
return 0;
}
color[x].se = c;
return 1;
}
void paint(int x, int y, int c) {
while (x != y) {
pii now = f[x];
if (paint(now.se, c)) {
flag = true;
c1 = color[now.se].fi;
c2 = color[now.se].se;
}
x = now.fi;
}
}
void dfs(int u, int fa, int t) {
if (flag) return;
f[u] = MP(fa, t);
vis[u] = ++dfn;
for (auto it : G[u]) {
int v = it.fi, id = it.se;
if (v == fa) continue;
if (!vis[v]) {
dfs(v, u, id);
} else if (vis[v] < vis[u]) {
if (flag) continue;
paint(u, v, id);
}
}
}
int d[N];
bool ok(int id, int c) {
return color[id].fi == c || color[id].se == c || id == c;
}
void find() {
for (int i = 1; i <= m; i++) {
if (ok(i, c1) || ok(i, c2)) {
int u = edges[i].fi, v = edges[i].se;
nG[u].push_back(v);
nG[v].push_back(u);
++d[u], ++d[v];
}
}
}
vector <vector <int>> cyc(3);
int S, T, t;
void go(int u, int fa) {
if (u == T) return;
for (auto v : nG[u]) if (v != fa) {
cyc[t].push_back(v);
go(v, u);
if (u == S) ++t;
}
}
void run() {
cin >> n >> m;
flag = false;
t = dfn = 0;
for (int i = 0; i < 3; i++) {
cyc[i].clear();
}
for (int i = 1; i <= n; i++) {
G[i].clear();
nG[i].clear();
vis[i] = d[i] = 0;
}
for (int i = 1; i <= m; i++) {
color[i] = MP(-1, -1);
}
edges.clear(), edges.push_back(MP(0, 0));
for (int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
G[u].push_back(MP(v, i));
G[v].push_back(MP(u, i));
edges.push_back(MP(u, v));
}
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
dfs(i, 0, 0);
}
}
if (!flag) {
cout << -1 << '\n';
return;
}
find();
S = -1, T = -1;
for (int i = 1; i <= n; i++) {
if (d[i] >= 3) {
if (S == -1) {
S = i;
} else if (T == -1) {
T = i;
}
}
}
go(S, 0);
cout << S << ' ' << T << '\n';
for (int i = 0; i < 3; i++) {
cout << sz(cyc[i]) + 1 << ' ' << S;
for (auto it : cyc[i]) {
cout << ' ' << it;
}
cout << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
freopen("grand.in", "r", stdin);
freopen("grand.out", "w", stdout);
int T; cin >> T; while(T--)
run();
return 0;
}
H. Hidden Supervisors
题意:
给定一个森林,现在每棵树两两相邻结点可以匹配,一个结点最多只能匹配一次。
现在将所有树拼接为一颗树,要求怎么拼接,最后的匹配对数最大。
思路:
- 对于一颗树,显然自底向上进行两两匹配最优。最后一颗树只会剩下0/1个根节点以及若干个叶子结点,接下来考虑不同树的"叶子-根"的匹配。
- 考虑拼接,直接将剩下\(1\)个根节点的树拼接到前面结点中即可,并且更新树的叶子结点;如果前面没有结点,则直接与树根相连,但此时不会产生新的匹配。
- 拼接时要按照叶子结点从大到小的顺序进行拼接,这样更新过后的结点数会更多,更有利于后续树根的匹配。
细节见代码:
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/11 17:03:22
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int n;
int fa[N];
bool vis[N];
int ans, tot;
vector <int> G[N], t;
vector <pair<vector<int>, int>> a;
void dfs(int u) {
t.push_back(u);
for (auto v : G[u]) {
dfs(v);
if (!vis[u] && !vis[v]) {
vis[u] = vis[v] = true;
++ans;
}
}
}
void gao(int u) {
t.clear();
dfs(u);
vector <int> tmp = t;
t.clear();
for (auto it : tmp) {
if (!vis[it]) {
t.push_back(it);
}
}
int f = 0;
for (int i = 0; i < sz(t); i++) {
if (fa[t[i]] == 0 && t[i] != 1) {
swap(t[sz(t) - 1], t[i]);
f = 1;
break;
}
}
a.push_back(MP(t, f));
}
void run() {
freopen("hidden.in", "r", stdin);
freopen("hidden.out", "w", stdout);
cin >> n;
for (int i = 2; i <= n; i++) {
cin >> fa[i];
if (fa[i] > 0) {
G[fa[i]].push_back(i);
}
}
for (int i = 1; i <= n; i++) {
if (fa[i] == 0) {
gao(i);
}
}
vector <vector <int>> v1;
vector <int> v0;
for (auto& it : a) if (sz(it.fi)) {
if (it.se) v1.push_back(it.fi);
else {
for (auto& it2 : it.fi) {
v0.push_back(it2);
}
}
}
sort(all(v1), [&] (vector <int> A, vector <int> B) {
return sz(A) > sz(B);
});
for (auto& v : v1) {
if (sz(v0)) {
++ans;
fa[v[sz(v) - 1]] = v0.back();
v0.pop_back();
v.pop_back();
}
if (sz(v)) {
for (auto it : v) {
v0.push_back(it);
}
}
}
cout << ans << '\n';
for (int i = 2; i <= n; i++) {
if (fa[i] == 0) fa[i] = 1;
cout << fa[i] << " \n"[i == n];
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
I. Intelligence in Perpendicularia
答案即为总边长减去里面的边长。
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define TM "intel"
int xs[1007], ys[1007];
int main() {
#ifndef LOCAL
freopen(TM".in", "r", stdin);
freopen(TM".out", "w", stdout);
#endif
int n; scanf("%d", &n);
for(int i=0; i<n; i++) {
scanf("%d%d", &xs[i], &ys[i]);
xs[i]+=1000001;
ys[i]+=1000001;
}
int mx,my,Mx,My;
mx=Mx=xs[0], my=My=ys[0];
for(int i=0; i<n; i++) mx=min(mx,xs[i]), my=min(my,ys[i]), Mx=max(Mx,xs[i]), My=max(My,ys[i]);
xs[n]=xs[0], ys[n]=ys[0];
long long ans1=0, ans2=0;
for(int i=1; i<=n; i++) {
int x1=xs[i], x2=xs[i-1];
int y1=ys[i], y2=ys[i-1];
if(x1==x2) {
if(y1>y2) swap(y1,y2);
int v=y2-y1;
ans2+=v;
} else {
if(x1>x2) swap(x1,x2);
int v=x2-x1;
ans1+=v;
}
}
ans1 -= (Mx-mx)*2;
ans2 -= (My-my)*2;
printf("%lld\n", ans1+ans2);
return 0;
}
K. Kotlin Island
签到。
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/11 13:24:07
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 100 + 5;
int r, c, n;
int rows[N], cols[N];
void run() {
freopen("kotlin.in", "r", stdin);
freopen("kotlin.out", "w", stdout);
cin >> r >> c >> n;
int x, y;
for (int i = 1; 1ll * i * i <= n; i++) {
if (n % i == 0) {
x = i - 1, y = n / i - 1;
if (2 * x + 1 <= r && 2 * y + 1 <= c) {
break;
}
x = n / i - 1, y = i - 1;
if (2 * x + 1 <= r && 2 * y + 1 <= c) {
break;
}
}
}
if (2 * x + 1 <= r && 2 * y + 1 <= c) {
for (int i = 2; i <= 2 * x; i += 2) {
rows[i] = 1;
}
for (int i = 2; i <= 2 * y; i += 2) {
cols[i] = 1;
}
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
if (rows[i] || cols[j]) {
cout << "#";
} else cout << ".";
}
cout << '\n';
}
} else {
cout << "Impossible" << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
L. Little Difference
题意:
给定一个数\(n,n\leq 10^{18}\),将其分为若干个相差至多为\(1\)的数的乘积,如果有无限个则输出\(-1\)。
思路:
显然最后的分解式中有\(1\)则有无限多个分解方案,此时只可能出现在\(n=1,n=2\)的情况中。
分解式中有\(1,2\)个数的情况我们可以直接考虑,接下来就处理分解式中有大于\(2\)个数的情况,此时每个数最多为\(10^6\)。那么我们可以直接枚举分解式中较小的那个数即可。
详见代码:
Code
/*
* Author: heyuhhh
* Created Time: 2020/6/11 14:13:21
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
freopen("little.in", "r", stdin);
freopen("little.out", "w", stdout);
ll n; cin >> n;
ll p = n;
while (p % 2 == 0) {
p /= 2;
}
if (p == 1) {
cout << -1 << '\n';
return;
}
vector <vector <ll>> ans;
ans.push_back({n});
ll t = sqrt(n + 0.5);
while (t * t > n) --t;
if (t * t == n) {
ans.push_back({t, t});
}
if (t * (t + 1) == n) {
ans.push_back({t, t + 1});
}
for (int i = 2; i <= min(n, 1000000ll); i++) {
if (n % i) continue;
vector <ll> res;
res.push_back(i);
ll x = n / i;
while (x % i == 0) {
x /= i;
res.push_back(i);
}
if (x == 1) {
ans.push_back(res);
continue;
}
ll x2 = x;
if (x % (i + 1) == 0) {
while (x % (i + 1) == 0) {
x /= (i + 1);
}
if (x == 1) {
x = x2;
while (x % (i + 1) == 0) {
x /= (i + 1);
res.push_back(i + 1);
}
sort(all(res));
ans.push_back(res);
}
}
}
vector <vector<ll>> result;
sort(all(ans));
result.push_back(ans[0]);
for (int i = 1; i < sz(ans); i++) {
if (ans[i] != ans[i - 1]) {
result.push_back(ans[i]);
}
}
cout << sz(result) << '\n';
for (auto seq : result) {
cout << sz(seq);
for (auto it : seq) {
cout << ' ' << it;
}
cout << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
重要的是自信,一旦有了自信,人就会赢得一切。