• Codeforces Round #673 Div. 2


    A. Copy-paste

    给定一串数组,可以选定两个数,将其中一个数加上另外一个数。每个数都不能超过个最大值K,问最多能进行几次这样的操作。

    排序,其他都加上最小的数即可。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <utility>
    #include<map>
    #include<queue>
    #include<sstream>
    #define lc(i) (2*i+1)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const ll mod = 998244353 ;
    ll dataa[1000000 + 5];
    int main(){
    	ll n;
    	cin >> n;
    	while (n--)
    	{
    		ll m, k;
    		ll ans = 0;
    		cin >> m >> k;
    		for (int i = 0; i < m; i++)scanf("%lld", &dataa[i]);
    		sort(dataa, dataa + m);
    		for (int i = 1; i < m; i++)ans += (k - dataa[i]) / dataa[0];
    		cout << ans << '
    ';
    	}
    }
    

    B. Two Arrays

    给定个值T,和一串数列,将其分为两部分,使每部分中一对数相加等于T的对数最小

    排序,对于每个数x,二分T-x,标记上不同的颜色,x=T/2时,标记一半的x为黑,另一半为白。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <utility>
    #include<map>
    #include<queue>
    #include<sstream>
    #define lc(i) (2*i+1)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const ll mod = 998244353;
    P dataa[1000000 + 5];
    int col[1000000 + 5] = {};
    bool cmp(P a, P b) {
    	return a.first < b.first;
    }
    int main() {
    	ll n;
    	cin >> n;
    	while (n--)
    	{
    		ll m, k;
    		ll ans = 0;
    		cin >> m >> k;
    		for (int i = 0; i < m; i++)scanf("%lld", &dataa[i].first), col[i] = -1, dataa[i].second = i;
    		sort(dataa, dataa + m);
    		for (int i = 0; i < m; i++) {
    			if (col[dataa[i].second] == -1) {
    				col[dataa[i].second] = 0;
    				ll l = lower_bound(dataa + i + 1, dataa + m, P(k - dataa[i].first, 0), cmp) - dataa;
    				if (l == m)continue;
    				if (dataa[l].first != dataa[i].first)
    					for (; dataa[l].first == k - dataa[i].first; l++)
    						col[dataa[l].second] = 1;
    				else {
    					int tmp = 0;
    
    					for (; dataa[l].first == k - dataa[i].first&&l<m; l++)
    						col[dataa[l].second] = tmp ^ 1, tmp ^= 1;
    				}
    			}
    
    		}
    		for (int i = 0; i < m; i++)
    			printf("%d ", col[i]);
    		printf("
    ");
    	}
    }
    

    C. k-Amazing Numbers

    定义K-number为在数组中任意长度都为K的区间内都出现的最小数,输出K等于1到n的K-number

    维护每个数字在数组中出现的位置,从小到大寻找该数字对应的最小K。

    可以知道,当一个数满足K-number,当K更大时这个数也能满足。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <utility>
    #include<map>
    #include<queue>
    #include<sstream>
    #define lc(i) (2*i+1)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const ll mod = 998244353 ;
    int dataa[1000000 + 5];
    int datab[1000000 + 5];
    int datac[1000000 + 5];
    int ans[1000000 + 5] = {};
    vector<int> e[300000 + 5];
    bool cmp(P a, P b) {
    	return a.first < b.first;
    }
    int main(){
    	ll n;
    	cin >> n;
    	while (n--)
    	{
    		ll m;
    		cin >> m;
    		for (int i = 0; i < m; i++)scanf("%lld", &dataa[i]),ans[i]=-1,datab[i]=dataa[i],e[i]=vector<int>(),e[i].push_back(-1);
    		ans[m] = -1;
    		sort(dataa, dataa + m);
    		//sort(datac, datac + m);
    		ll len = unique(dataa, dataa + m) - dataa;
    		for (int i = 0; i < m; i++)datab[i] =lower_bound(dataa,dataa+len,datab[i])-dataa,e[datab[i]].push_back(i);
    		for (int i = 0; i < len; i++) {
    			ll max1 = e[i][0];
    			e[i].push_back(m);
    		
    			for (int j = e[i].size() - 1; j > 0; j--)e[i][j] = e[i][j] - e[i][j - 1],max1=max(max1,(ll)(e[i][j]));
    			if (ans[max1] == -1)ans[max1] = dataa[i];
    		}
    		for (int i = 1; i <=m; i++) {
    			if (i != 1 && (ans[i] == -1||(ans[i]>ans[i-1]&&ans[i-1]!=-1)))ans[i] = ans[i - 1];
    			printf("%d ", ans[i]);
    		}
    		printf("
    ");
    	}
    }
    

    D. Make Them Equal

    给定一个数列,可以进行以下操作:

    选定i,j,x

    ai=ai-x*i,aj=aj+x*i

    在3n次内令数列全部相同

    当我们把所有数都加到a1上,我们就能随意分配数字

    我们可以先把a1的一部分转移到ai上,令ai%i==0,再把ai全部转哟到a1.

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <utility>
    #include<map>
    #include<queue>
    #include<sstream>
    #define lc(i) (2*i+1)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const ll mod = 998244353;
    int dataa[1000000 + 5];
    int ans[1000000 + 5][3] = {};
    bool cmp(P a, P b) {
    	return a.first < b.first;
    }
    int main() {
    	ll n;
    	cin >> n;
    	while (n--)
    	{
    		ll cnt = 0;
    		ll m;
    		cin >> m;
    		dataa[0] = 0;
    		for (int i = 1; i <= m; i++) {
    			scanf("%d", &dataa[i]);
    			dataa[0] += dataa[i];
    		}
    		if ((dataa[0] % m)) {
    			printf("-1
    ");
    			continue;
    		}
    		for (int i = 2; i <= m; i++) {
    			if (dataa[i] % i == 0) {
    				ans[cnt][0] = i;
    				ans[cnt][1] = 1;
    				ans[cnt++][2] = dataa[i] / i;
    			}
    			else {
    				ans[cnt][0] = 1;
    				ans[cnt][1] = i;
    				ans[cnt++][2] = i - dataa[i] % i;
    				ans[cnt][0] = i;
    				ans[cnt][1] = 1;
    				ans[cnt++][2] = (dataa[i]+i-1) / i;
    			}
    		}
    		for (int i = 2; i <= m; i++) {
    			ans[cnt][0] = 1;
    			ans[cnt][1] = i;
    			ans[cnt++][2] = dataa[0]/m;
    		}
    		printf("%d
    ", cnt);
    		for (int i = 0; i <cnt; i++)printf("%d %d %d
    ", ans[i][0], ans[i][1], ans[i][2]);
    	}
    }
    

    E. XOR Inverse

    给定数组,找到个数x,用数组每个数异或x,新数组中逆序对最少

    先用字典树维护数组中的二进制数,并且每个节点中存着该节点的编号。从高到低位贪心选取逆序对小的(0或1)

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <utility>
    #include<map>
    #include<queue>
    #include<sstream>
    #define lc(i) (2*i+1)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    ll trie[5000000][2];
    ll tot = 0;
    ll ans[40][2] = {};
    vector<int> e[5000000];
    void ins(int k, int pos) {
    	ll p = 0,c;
    	for (int i = 30; i >= 0; i--) {
    		c = (k>>i) & 1;
    		if (trie[p][c] == 0)trie[p][c] = ++tot;
    		p = trie[p][c];
    		e[p].push_back(pos);
    	}
    }
    void dfs(int k, int pos) {
    	//if (pos == -1)return;
    	ll l = trie[k][0], r = trie[k][1];
    	if (l)dfs(l, pos - 1);
    	if (r)dfs(r, pos - 1);
    	if (!trie[k][0] || !trie[k][1])return;
    	
    	ll tmp = 0, ans1 = 0;
    	for (int i = 0; i < e[l].size(); i++) {
    		while (tmp < e[r].size() && e[r][tmp] < e[l][i])tmp++;
    		ans1 += tmp;
    	}
    	ans[pos][0] += ans1;
    	ans[pos][1] += (ll)e[l].size() * e[r].size() - ans1;
    }
    int main() {
    	ll n;
    	cin >> n;
    	for (int i = 1; i <= n; i++) {
    		int tmp;
    		scanf("%d", &tmp);
    		ins(tmp, i);
    	}
    	dfs(0, 30);
    	ll res=0, x=0;
    	for (int i =0; i <= 30; i++) {
    		if (ans[i][0] <= ans[i][1])
    			res += ans[i][0];
    		else {
    			res += ans[i][1];
    			x += (1 << i);
    		}
    	}
    	cout << res << ' ' << x;
    }
    
    K-ON!!
  • 相关阅读:
    如何实现浏览器内多个标签页之间的通信?
    vue组件库的基本开发步骤(源代码)
    vue组件库的基本开发步骤
    Websocket原理
    TCP和UDP的区别
    一句话概括 tcp三次握手
    简单说一下你对http和https的理解
    .Ajax(async异步与sync同步)
    get和post请求方式的区别
    面试易忽略状态码
  • 原文地址:https://www.cnblogs.com/pophirasawa/p/13799711.html
Copyright © 2020-2023  润新知