A. Musical Puzzle
思路:判断一下每每两个连接在一起的字符组成的字符串种类数
代码
#include
#include
#include
B.Restore the Weather
思路:用pair
#include
#include
#include
C. Vlad Building Beautiful Array
思路:如果数组全是偶数或奇数,输出“YES”,否则找到数组中最小的数,判断是否的奇数,如果是奇数,则通过这个数,能让数组所有数变成奇数,这是输出YES.
#include
#include
#include
D. Flipper
思路:太麻烦了,不想说
#include
#include
#include
E. Round Dance
思路:这个数组里面所有数值连在一起不是环就是链,如果找最大值就是判断环和链的个数,这个可以用并查集,如果是找最小值的话,就是找最大的环,但是数组中的这些小环是不可能拆开组成最大环的,而链可以一起组成最大环,所以找完最大环后,还有把这些小环的个数加上。找环有个技巧,也不算是吧,如果一个数组的子序列的下标组成的一个数组是它们的fa[]组成的一个数组的一个排列,则这个子序列构成一个环,即
fa 1 2 3
idex 3 2 1
PS:下面arr是上面的fa,而下面的fa是第i个数的祖宗,两个数构成的环按照题目要求,是不算环的,算链的
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 2e5 + 5;
int arr[MAXN], fa[MAXN], vis[MAXN];
priority_queue, greater> que[MAXN];
int find(int x)
{
if (fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
fa[i] = i, vis[i] = 0;
cin >> arr[i];
}
int MAX = 0, MIN = 0;
for (int i = 1; i <= n; ++i)
{
int fi = find(arr[i]);
fa[find(i)] = fi;
}
for (int i = 1; i <= n; ++i)
{
int fi = find(i);
que[fi].push(arr[i]), que[fi].push(i);
if (!vis[fi]) ++MAX;
++vis[fi];
}
int cnt = 0;
for (int i = 1; i <= n; ++i)
{
int flag = 0;
if (vis[i] > 2)
{
int a = 0, b = 0;
if (que[i].empty()) continue;
while (que[i].size())
{
a = que[i].top(), que[i].pop();
b = que[i].top(), que[i].pop();
if (a != b) flag = 1;
}
if (flag == 0)++MIN, cnt += vis[i];
}
}
cout << max(MIN + (cnt != n), 1) << " " << MAX << '\n';
}
return 0;
}
F,Ira and Flamenco
用滑动窗口,窗口里的数是第i个时段满足条件二和三,但不满足条件一的集合,求条件一可以用C的方式,即从含有a个数的窗口中取b个数的方法。由于可能出现重复的数,这时候用val维护每一个数出现的个数,ret则代表窗口内重复的数的个数和的乘积
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 2e6 + 5;
#define int unsigned long long
#define LL unsigned long long
int arr[MAXN], f[MAXN];
unordered_map val;
const int mod = 1e9 + 7;
LL qkpow(LL a, LL p, LL mod)
{
LL t = 1, tt = a % mod;
while (p)
{
if (p & 1)t = t * tt % mod;
tt = tt * tt % mod;
p >>= 1;
}
return t;
}
LL getInv(LL a, LL mod)
{
return qkpow(a, mod - 2, mod);
}
int C(int n, int m)
{
if (n < m) return 0;
int a = f[n];
int b = getInv(f[n - m], mod);
int c = getInv(f[m], mod);
return (((a * b) % mod) * c) % mod;
}
signed main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t;
cin >> t;
deque d;
f[0] = f[1] = 1;
for (int i = 2; i < MAXN; ++i)
f[i] = (f[i - 1] * i) % mod;
while (t--)
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> arr[i];
sort(arr + 1, arr + 1 + n);
for (int i = 1; i <= n; ++i) ++val[arr[i]];
int ans = 0, ret = 1;
for (int i = 1; i <= n; ++i)
{
while (d.size() && arr[i] - arr[d.front()] >= m)
{
if (d.size() >= m) ans = (ans + (ret * C(d.size(), m)) % mod) % mod;
ret = (getInv(val[arr[d.front()]], mod) * ret) % mod;
d.pop_front();
}
int flag = 0;
if ((d.size() && arr[d.back()] != arr[i]) || d.empty()) d.push_back(i), ret = (ret * val[arr[i]]) % mod;
}
if (d.size()) ans = (ans + (ret * C(d.size(), m)) % mod) % mod;
cout << ans << '\n';
d.clear(), val.clear();
}
return 0;
}