思路
赛时读错题了, 虽然说读对了不一定能做出来, 但是还是比较可惜
首先阐述一下题意, 对 \(S\) 数组进行插入和删除操作, 每次询问让你用 \(T\) 中的质数组合出 \(x\) , 然后将 \(S\) 中的数乘以 \(x\) 之后求最多的完全立方数个数
那么显然的, 我们对于每一个数, 都可以拆成质数之积, 那么显然的, 我们可以知道每个数需要什么质数才能凑成完全立方数
\(op = 1\)
如果这个数可能成为一个完全立方数, 我们记录这个数需要 \(T\) 中质数的个数, 这应该是一个 \(0, 1, 2\) 串串, 丢进去
时间复杂度 \(\mathcal{O} (M)\)
\(op = 2\)
扔出来
时间复杂度 \(\mathcal{O} (M)\)
\(op = 3\)
找最大, 结束
题解使用了 \(0, 1, 2 \ \rm{trie}\) , 但是被 \(\rm{klr}\) 的 \(\rm{pbds}\) 轻松冲过
还是稍微写一些 \(\rm{trie}\) , 补一下我的神秘基础
实现
代码
#include <bits/stdc++.h>
const int MAXM = 520;
const int MAXN = 5e6 + 1;
typedef long long ll;
void write(__int128 x) {
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
return;
}
int M;
int prime[MAXM];
int Q;
struct node {
int App; // 串串的出现次数
int son[3]; // 下一个节点
int prime;
__int128 x;
} Tree[MAXN];
int cnt = 1; // 0 为根节点
bool check(ll rest)
{
ll l = 1, r = 1000000;
while (l <= r)
{
ll mid = (l + r) >> 1;
if (mid * mid * mid == rest)
return 1;
mid * mid * mid < rest ? l = mid + 1 : r = mid - 1;
}
return 0;
}
std::vector<int> mstr;
std::set<int> leave;
void ins() {
ll num; scanf("%lld", &num);
mstr.clear();
for (int i = 1; i <= M; i++) {
int cnt = 0; while (!(num % prime[i])) cnt++, num /= prime[i];
mstr.push_back((3 - (cnt % 3)) % 3);
}
if (num != 1 && !check(num)) return;
ll now = 0;
__int128 nowx = 1;
for (int i = 0; i < M; i++) {
int ch = mstr[i];
for (int j = 1; j <= ch; j++) nowx *= prime[i + 1];
if (!Tree[now].son[ch]) Tree[now].son[ch] = cnt++;
now = Tree[now].son[ch];
Tree[now].prime = prime[i + 1];
Tree[now].x = nowx;
}
Tree[now].App++;
leave.insert(now);
}
void del() {
ll num; scanf("%lld", &num);
mstr.clear();
for (int i = 1; i <= M; i++) {
int cnt = 0; while (!(num % prime[i])) cnt++, num /= prime[i];
mstr.push_back((3 - (cnt % 3)) % 3);
}
if (num != 1 && !check(num)) return;
ll now = 0;
for (int i = 0; i < M; i++) {
int ch = mstr[i];
now = Tree[now].son[ch];
}
Tree[now].App--;
}
__int128 ansx;
int ans;
void solve()
{
while (Q--) {
int op; scanf("%d", &op);
if (op == 1) ins();
if (op == 2) del();
if (op == 3) {
ans = 0, ansx = 0;
for (auto i : leave) {
int now = i;
if (Tree[now].App == 0) {
continue;
}
__int128 x = Tree[now].x;
if (ans == Tree[now].App) ansx = std::min(ansx, x);
if (ans < Tree[now].App) ans = Tree[now].App, ansx = x;
}
write(ansx); printf("\n");
}
}
}
signed main()
{
scanf("%d", &M);
for (int i = 1; i <= M; i++)
scanf("%d", &prime[i]);
scanf("%d", &Q);
solve();
return 0;
}
总结
注意读题
字符串插入删除, 字典树是最快的
标签:return,int,质数,T2,mid,rm,CW,ll,12.19 From: https://www.cnblogs.com/YzaCsp/p/18617680