其他分享
首页 > 其他分享> > Codeforces Round #797 (Div. 3) D, E, F, G题题解

Codeforces Round #797 (Div. 3) D, E, F, G题题解

作者:互联网

Codeforces题解汇总

Round #797 div3

D. Black and White Stripe

固定长度最大子段和, 简单只贴代码了

Solution

#include<bits/stdc++.h>
typedef long long ll;
typedef std::pair<int, int> PII;
typedef std::pair<ll, ll> PLL;
typedef unsigned long long ull;
typedef double db;
#define arr(x) (x).begin(),(x).end()
#define x first
#define y second
#define pb push_back
#define mkp make_pair
#define endl "\n"
using namespace std;

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--){
		int n, k;
		cin >> n >> k;
		vector<int> pre(n + 1, 0);
		string s;
		cin >> s;
		s = " " + s;
		for(int i = 1; i <= n; i++){
			pre[i] = pre[i - 1] + (s[i] == 'B');
		}
		int ans = n;
		for(int i = k; i <= n; i++){
			ans = min(ans, k - (pre[i] - pre[i - k]));
		}
		cout << ans << endl;
	}
    return 0;
}

E. Price Maximization

双指针, 贪心, 排序, 或者 STL

题意

给了 \(n\) 个货品, \(n\) 是偶数, 每个货品有价值 \(a_i\) , 将货品两两配对, 两两配对和总价值为 \(w_i\), 给定 \(k\), 求 \(\Sigma \lfloor \frac{w_i}{k} \rfloor\) 最大值

数据范围
\(2\leq n \leq 2*10^5\)
\(1\leq k \leq 1000\)
\(0\leq a_i \leq 10^9\)

思路

Solution

#include<bits/stdc++.h>
typedef long long ll;
typedef std::pair<int, int> PII;
typedef std::pair<ll, ll> PLL;
typedef unsigned long long ull;
typedef double db;
#define arr(x) (x).begin(),(x).end()
#define x first
#define y second
#define pb push_back
#define mkp make_pair
#define endl "\n"
using namespace std;

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--){
		int n, k;
		cin >> n >> k;
		ll ans = 0;
		multiset<int> s;
		for(int i = 0; i < n; i++){
			int x;
			cin >> x;
			ans += x / k;
			s.insert(x % k);
		}
		while(!s.empty()){
			auto x = *s.begin();
			s.erase(s.begin());
			auto it = s.lower_bound(k - x);
			if(it != s.end()){
				s.erase(it);
				ans++;
			}
		}
		cout << ans << endl;
	}
    return 0;
}

F. Shifting String

置换, 环, 字符串最小循环节, LCM

题意

给定一个长度为 \(n\) 的字符串 \(s\), 和一个排列 \(P\) , 每次操作让 \(s_i = s_{P_i}\) , 询问至少经过多少次操作能让字符串与初始状态相同

数据范围
\(1\leq n \leq 200\)
\(1\leq p_i \leq n\)

思路

Solution

#include<bits/stdc++.h>
typedef long long ll;
typedef std::pair<int, int> PII;
typedef std::pair<ll, ll> PLL;
typedef unsigned long long ull;
typedef double db;
#define arr(x) (x).begin(),(x).end()
#define x first
#define y second
#define pb push_back
#define mkp make_pair
#define endl "\n"
using namespace std;
const int N = 210;
ll gcd(ll a, ll b){
	return b ? gcd(b, a % b) : a;
}

ll LCM(ll a, ll b){
	return a / gcd(a, b) * b;
}

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--){
		int n;
		string s;
		cin >> n >> s;
		s = " " + s;
		vector<bool> st(n + 1, false);
		vector<int> p(n + 1,0);
		for(int i = 1; i <= n; i++)
			cin >> p[i];
		ll ans = 1;
		for(int i = 1; i <= n; i++){
			if(st[i]) continue;
			string tmp = " ";
			int sz = 0;
			for(int j = i; !st[j]; j = p[j]){
				st[j] = true;
				tmp += s[j];
				sz++;
			}
			vector<int> ne(sz + 1, 0);
			ne[1] = 0;
			for(int i = 2, j = 0; i <= sz; i++){
				while(j && tmp[j + 1] != tmp[i]) j = ne[j];
				if(tmp[i] == tmp[j + 1]) j++;
				ne[i] = j;
			}
			ll len = sz - ne[sz];
			if(sz % len == 0)
				ans = LCM(ans, len);
			else
				ans = LCM(ans, sz);
		}
		cout << ans << endl;
	}
    return 0;
}

G. Count the Trains

STL, 二分, 思维

题意

给了 \(n\) 个点, 每个点有值为 \(a_i\) , 从左往右形成序列, 对于序列上下标 \(i\) 位置, 值为 \(min\{a_j\}, (j\leq i)\)

有 \(m\) 次操作, 输入 \(k, d\) , 每次操作对 a[k] -= d , 询问每次操作完之后, 序列中有多少个不同的数 ?

思路

Solution

#include<bits/stdc++.h>
typedef long long ll;
typedef std::pair<int, int> PII;
typedef std::pair<ll, ll> PLL;
typedef unsigned long long ull;
typedef double db;
#define arr(x) (x).begin(),(x).end()
#define x first
#define y second
#define pb push_back
#define mkp make_pair
#define endl "\n"
using namespace std;
map<int, int> mp;

void add(int i, int x){
	mp[i] = x;
	auto it = mp.find(i);
	if(it != mp.begin() && prev(it)->second <= it->second){
		mp.erase(it);
		return ;
	}
	while(next(it) != mp.end() && next(it)->second >= it->second)
		mp.erase(next(it));
}

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--){
		mp.clear();
		int n, m;
		cin >> n >> m;
		vector<int> a(n + 1, 0);
		for(int i = 1; i <= n; i++){
			cin >> a[i];
			add(i, a[i]);
		}
		while(m--){
			int k, d;
			cin >> k >> d;
			a[k] -= d;
			add(k, a[k]);
			cout << mp.size() << " ";
		}
		cout << endl;
	}
    return 0;
}

标签:797,typedef,int,题解,cin,long,leq,Div,define
来源: https://www.cnblogs.com/Roshin/p/cfround797div3.html