• CF1687E Become Big For Me 【minmax 容斥,构造】


    给定 \(n\) 个正整数 \(a_1,\cdots,a_n\),构造 \(k_1+k_2\le 10^5\) 个子序列 \(b_1,\cdots,b_{k_1},c_1,\cdots,c_{k_2}\) 满足:

    • \(\sum|b_i|+\sum|c_i|\le 10^6\)
    • \(\prod \text{lcm}(b_i)/\prod \text{lcm}(c_i)=\gcd_{i\ne j}\{a_ia_j\}\)

    \(n\le 10^5\)\(a_i\le 10^6\),保证有解。


    由 min-max 容斥知 \(\gcd_{i\ne j}\{a_ia_j\}=\prod_{\varnothing\ne T\subset S}\operatorname{lcm}(T)^{(-1)^{|T|}(|T|-2)}\),问题转化为选择尽可能少的一些数 \(c_1,\cdots,c_k\) 使得 \(\gcd_{i\ne j}\{a_ia_j\}=\gcd_{i\ne j}\{c_ic_j\}\)

    先考虑要求 \(\gcd\{a_i\}=\gcd\{c_i\}\) 怎么办,任取一个元素 \(x\)从小到大枚举 \(x\) 的质因子 \(p\),把 \(\nu_p(a_i)\) 取到最小的 \(a_i\) 加入,注意如果 \(\nu_p\) 已经取到最小就不用加了,选了至多 \(\omega(x)+1=8\) 个数,实际上若选了 \(8\) 个数则可以把 \(x\) 扔掉,否则第一次选的 \(a_i\) 缺一个最小质因子,多一个别的质因子,这就爆值域了。

    设这样构造的子集是 \(g(a)\),则对原问题用 \(g(a)\cup g(a\backslash g(a))\) 即可。

    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef pair<int, int> pii;
    template<typename T>
    bool chmin(T &a, const T &b){if(a > b) return a = b, 1; return 0;}
    const int N = 100003, M = 1000003;
    int n, a[N], pri[N], mp[M], tot;
    bitset<M> notp;
    vector<pii> vc[N];
    vector<int> pos, res;
    vector<pair<vector<int>, bool> > ans;
    int qry(int i, int p){
    	auto it = lower_bound(vc[i].begin(), vc[i].end(), MP(p, 0));
    	return it != vc[i].end() && it -> fi == p ? it -> se : 0;
    }
    void work(){
    	if(pos.empty()) return;
    	vector<int> del;
    	for(auto [p, c] : vc[pos[0]]){
    		int nx = 0, now = c;
    		for(int i = 0;i < del.size();++ i) chmin(now, qry(pos[del[i]], p));
    		for(int i = 1;i < (int)pos.size() && now;++ i)
    			if(chmin(now, qry(pos[i], p))) nx = i;
    		if(nx) del.push_back(nx);
    	}
    	sort(del.begin(), del.end());
    	del.erase(unique(del.begin(), del.end()), del.end());
    	if(del.size() < 7) del.insert(del.begin(), 0);
    	for(int i = (int)del.size() - 1;i >= 0;-- i){
    		res.push_back(pos[del[i]]);
    		pos.erase(pos.begin() + del[i]);
    	}
    }
    int main(){
    	ios::sync_with_stdio(0);
    	notp.set(0); notp.set(1);
    	for(int i = 2;i < M;++ i){
    		if(!notp.test(i)){mp[i] = i; pri[tot++] = i;}
    		for(int j = 0;j < tot && i * pri[j] < M;++ j){
    			notp.set(i * pri[j]);
    			mp[i * pri[j]] = pri[j];
    			if(!(i % pri[j])) break;
    		}
    	}
    	cin >> n;
    	for(int i = 0;i < n;++ i){
    		cin >> a[i]; int x = a[i];
    		while(x > 1){
    			int p = mp[x], c = 0;
    			while(!(x % p)){x /= p; ++ c;}
    			vc[i].emplace_back(p, c);
    		}
    	}
    	pos.resize(n);
    	iota(pos.begin(), pos.end(), 0);
    	work(); work();
    	int m = res.size();
    	for(int S = 1;S < (1 << m);++ S){
    		int pc = __builtin_popcount(S), ct = (pc & 1) ? 2 - pc : pc - 2;
    		bool flg = ct < 0; if(flg) ct = -ct;
    		vector<int> hah;
    		for(int i = 0;i < m;++ i) if(S >> i & 1) hah.push_back(res[i]);
    		sort(hah.begin(), hah.end());
    		while(ct --) ans.emplace_back(hah, flg);
    	}
    	printf("%d\n", (int)ans.size());
    	for(auto [hah, flg] : ans){
    		printf("%d %d", flg, (int)hah.size());
    		for(int i : hah) printf(" %d", i + 1);
    		putchar('\n');
    	}
    }
    
  • 相关阅读:
    在vm中安装ubuntu 11 并部署 xampp集成环境步骤
    修改xampp的mysql默认密码
    linux下重命名文件的命令
    IE6下DIV最小高度不能为0的解决方法
    linux下解压tar.gz 文件和 tar.bz2 文件命令
    linux svn 使用
    win7 下设置java环境变量
    在linux下安装svn软件rabbitvcs
    linux下开启ssh服务
    【转】DataSet与DataTable的区别
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/16347614.html
Copyright © 2020-2023  润新知