A - How Much Does Daytona Cost?
题意:给你一列数,问你是否存在一个子列使得子列中出现次数最多的数为k,显然只要k在序列中肯定可以做到
思路:find找一下序列中有没有出现k
题意:让你构造一列长度为n的数满足a[i-2]+a[i-1[!=3*a[i];
思路:其实容易发现连续的一列数肯定满足这个条件,所以直接输出一列长度为n的数即可
题意:问你从1~n中取k个数,能不能让这个k个数的和等于x
思路:由于是在1~n中取,都是连续的,所以这个数只要在最小的k个数和最大的k个数之间即可(因为这样一定可以找到k个数使得他们的和等于x)
思路:差分维护每个位置的翻转次数,如果是奇数就翻转到对称位置,如果是偶数就不变
代码:
void solve()
{
int n, k; // 每个区间记录翻转,如果翻转次数为奇数次就是对称的位置如果是偶数次就是原位置
cin >> n >> k;
string s;
cin >> s;
s = " " + s;
vector<int> l(k + 1), r(k + 1);
for (int i = 1; i <= k; i++)
cin >> l[i];
for (int i = 1; i <= k; i++)
cin >> r[i];
int q;
cin >> q;
vector<int> cnt(n + 1, 0);
for (int i = 1; i <= q; i++)
{
int x;
cin >> x;
int pos = upper_bound(l.begin() + 1, l.end(), x) - l.begin() - 1; // 找到第一个大于他的数再前面一个就是他所在的区间
int temp = min(x, l[pos] + r[pos] - x);
cnt[temp]++; // 记录每个位置被翻转的次数
}
for (int i = 1; i <= k; i++)
{
int mid = (l[i] + r[i]) >> 1;
int sum = 0;
for (int j = l[i]; j <= mid; j++)
{
sum += cnt[j];
if (sum & 1)
swap(s[j], s[l[i] + r[i] - j]);
}
}
// cout << s << endl;有空格
for (int i = 1; i <= n; i++)
cout << s[i];
cout << endl;
}