CF1687E Become Big For Me
CF1687E Become Big For Me
题意
给你长度为 \(n\) 的序列 \(\{a_i\}\)。初始你有一个实数 \(v=1\)。你可以进行至多 \(10^5\) 次操作后,把 \(v\) 变成 \(\gcd\{a_i \times a_j\}\)。操作可以是两种中任意一种:
你可以选择任意序列 \(a\) 的非空子集 \(\{b\}\)。
- \(v \gets v \times \text{lcm}\{b\}\)
- \(v \gets \frac{v}{ \text{lcm}\{b\}}\)
要求 \(\sum |b| \le 10^6\)。
\(n \le 10^5, a_i \le 10^6\)
思路
参考 zky 的做法。
显然可以改为考虑质因数的指数。实数 \(v\) 也可以质因数分解,只是可能有负数指数。
\(10^6\) 以内最多只有 \(7\) 种质因数。
两个操作分别是指数相加或者相减。
\(\gcd\{a_i \times a_j\}\) 就是每个质因数的指数是该质因数在整个序列所有数的最小指数加次小指数。
考虑把最小质数加次小指数刻画地更好一些,然后采用 min-max 容斥,变成若干 \(\text{lcm}\) 相乘除。
因为我们的操作只能乘除 \(\text{lcm}\),所以要把问题刻画成只有 \(\gcd,\text{lcm}\) 的乘除法。
最小指数显然可以乘上 \(\gcd\{a_i\}\)。
求次小指数,我们就是要找扔掉最小指数之后的 \(\gcd\)。
次小指数可以表示成 \(\gcd\{a_i\} \times \prod_i \frac{\gcd_{i \neq j} \{a_j\}}{\gcd\{a_j\}}\)。
如果 \(a_i\) 是最小值,后面那里就会变成次小值除以最小值,所以前面还要乘回一个最小值。否则后面那里就是 \(1\)。
所以原问题刻画成 \((\gcd\{a_i\})^2 \prod_i \frac{\gcd_{i \neq j} \{a_j\}}{\gcd\{a_j\}}\)。
对 \(a_i\) 进行质因数分解。因为前面的 \(\gcd\) 只有最多 \(8\) 个数字有用(每个数字只有 \(7\) 种质因子,即最多有 \(7\) 个指数与 \(\gcd\) 不同,所以最多选择 \(8\) 个数即可),反演后就是 \(2^8\) 次操作。
后面那里我们也只要有最小值的地方。也是最多只有 \(8\) 个 \(i\) 有用。然后每次计算除掉 \(i\) 的 \(\gcd\) 时,也只有最多 \(8\) 个数字有用。所以是 \(8 \times 2^8\) 次操作。
复杂度 \(O(n\log n + n \omega(\sqrt{a}) + \sqrt{a})\)。\(\omega(a)\) 表示 \(a\) 以内的质因子个数。这里把预处理质因子认为是 \(\sqrt{a}\)。实际上我写的埃氏筛,反正不是复杂度瓶颈。特判一下 \(> \sqrt{a}\) 的质因子。
精细实现应该可以砍掉 \(n \log n\),但是这又不是复杂度瓶颈。所以没有必要。
code
不想写。咕咕。
输出怎么这么多要求/fn
wrong answer Sorry, wrong answer.
哪里错了啊?
RE 了,回宿舍了,咕咕。
变成 TLE 了……
我写的什么鬼啊,写成最劣接近 \(O(n^2)\) 了。
看看我要再交几次才能过,已经交了好多次了跑得好慢呐。怎么这么多个点啊……
\(214\) 个点测了 \(9min\),但是最慢点是 \(218ms\)。
代码很烂,因为是晚上写的。建议不要看。
#include<bits/stdc++.h>
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
typedef long long ll;
namespace wing_heart {
constexpr int N=1e5+7,V=1e6;
int n,a[N],_a[N];
bool vi[V+5];
vector<int> pri;
int posmn[N<<1],pos2mn[N<<1],_mn[N<<1],_mn2[N<<1];
void init() {
for(int i=2;i*i<=V;i++) {
if(!vi[i]) {
pri.push_back(i);
for(int j=i;i*j<=V;j++) vi[i*j]=1;
}
}
}
typedef pair<int,int> pii;
#define fi first
#define se second
vector<int> mnvec,mn[N],mn2[N];
int gcd(int a,int b) { return b? gcd(b,a%b): a; }
int cntk;
vector<vector<int> > ans;
bool used[N];
int g;
bool bl[N<<1];
map<int,int> mp;
void main() {
sf("%d",&n);
rep(i,1,n) sf("%d",&a[i]),_a[i]=a[i], g=gcd(g,a[i]);
init();
int c=0;
for(int x : pri) {
if(g%x==0) {
while(g%x==0) g/=x;
}
++c;
}
if(g!=1) pri.push_back(g), mp[g]=1;
rep(i,1,n) {
int c=0;
for(int x : pri) {
int cnt=0;
while(_a[i]%x==0) _a[i]/=x, ++cnt;
if(!posmn[c] || cnt<_mn[c]) pos2mn[c]=posmn[c], _mn2[c]=_mn[c], posmn[c]=i, _mn[c]=cnt;
else if(!pos2mn[c] || cnt<_mn2[c]) pos2mn[c]=i, _mn2[c]=cnt;
++c;
}
if(_a[i]!=1 && mp.find(_a[i])==mp.end()) {
mp[_a[i]]=1;
++c;
if(i==1) posmn[c]=i, _mn[c]=1, pri.push_back(_a[i]);
else if(i==2) pos2mn[c]=i, _mn2[c]=1, posmn[c]=1, pri.push_back(_a[i]);
else posmn[c]=1, pos2mn[c]=2;
}
}
rep(i,0,(int)pri.size()-1) {
int x=posmn[i];
if(!x) continue;
if(!used[x]) mnvec.push_back(x), used[x]=1;
mn[x].push_back(i);
mn2[pos2mn[i]].push_back(i);
}
int s=mnvec.size();
rep(i,1,(1<<s)-1) {
int k=__builtin_popcount(i);
vector<int> b;
b.push_back((k-1)&1? 1: 0);
rep(j,0,s-1) if((i>>j)&1) b.push_back(mnvec[j]);
ans.push_back(b);
}
auto tgcd=ans;
for(vector<int> &x : tgcd) ans.push_back(x), x[0]^=1;
for(int i : mnvec) {
vector<int> tvec;
int sum=0;
for(int x : mn[i]) bl[x]=1, ++sum;
for(int j : mnvec) if(j^i) {
tvec.push_back(j);
for(int x : mn2[j]) if(bl[x]) bl[x]=0, --sum;
}
if(sum) rep(j,1,n) if(!used[j]) {
bool fl=0;
for(int x : mn2[j]) if(bl[x]) {
bl[x]=0, --sum;
fl=1;
}
if(fl) {
tvec.push_back(j);
if(!sum) break;
}
}
for(auto x : tgcd) ans.push_back(x);
int siz=tvec.size();
rep(j,1,(1<<siz)-1) {
int k=__builtin_popcount(j);
vector<int> b;
b.push_back((k-1)&1? 1: 0);
rep(q,0,siz-1) if((j>>q)&1) b.push_back(tvec[q]);
ans.push_back(b);
}
}
pf("%d\n",(int)ans.size());
for(auto x : ans) {
pf("%d %d ",x[0],(int)x.size()-1);
sort(x.begin()+1,x.end());
rep(i,1,(int)x.size()-1) pf("%d ",x[i]); pf("\n");
}
}
}
int main() {
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("my.out","w",stdout);
#endif
wing_heart :: main();
}
本文来自博客园,作者:wing_heart,转载请注明原文链接:https://www.cnblogs.com/wingheart/p/18720598

浙公网安备 33010602011771号