11.23 周六
codeforces
Q1.1200 将一个序列分为若干集合,每个集合的和在一个区间内,问集合数量的最大值。
Q2.1400 长度为n的数组产生n-2个相邻三元组,问恰有1个元素不同的三元组的配对数。
Q3.1500 给定n个数组,设f(x)=max{任意次将x放入任意数组:x=mex{x,a[i]}},问f(0)+...+f(m)。(m<=1e9)
A1.前缀+二分:对于每个数作为起点二分找到满足条件的最左侧的数 细节较多。
双指针贪心 设s为维护的区间和 s<lim_l r++; s>lim_r l++。
A2.map+容斥:cnt_ab+cnt_ac+cnt_bc-3*cnt_abc 。
A3.结论:计算出每个数组的x1,x2关键点,设max_w=max(x1,x2),发现f(i)为max(i,max_w)。
牛客小白月赛105
C.大力讨论,写了一个小时挂了4发,应该一开始想一个好写的方法再动键盘的(早点重写的)。
D.并查集板题
E.括号匹配+反向答案:res[i]=n-栈里元素个数 / 也可生成一棵树
A1.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' //
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
const int mod = 998244353;
const int N = 10 + 5e5;
void _();
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
_();
return 0;
}
void _()
{
int n, L, R;
cin >> n >> L >> R;
vector<int> a(n + 1), pre(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i], pre[i] = pre[i - 1] + a[i];
int res = 0;
for (int st = 1; st <= n; st++)
{
if (a[st] > R)
continue;
if (a[st] >= L)
{
res++;
continue;
}
int l = st, r = n + 1;
while (r - l - 1)
{
int mid = l + r >> 1;
if (pre[mid] - pre[st - 1] >= L)
r = mid;
else
l = mid;
}
if (r > n)
continue;
if (pre[r] - pre[st - 1] > R)
continue;
// bug2(st, r);
res++;
st = r;
}
cout << res << endl;
}
A2.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' //
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
const int mod = 998244353;
const int N = 10 + 5e5;
void _();
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
_();
return 0;
}
void _()
{
int n;
cin >> n;
vector<int> a(n + 1);
map<pair<int, int>, int> cnt_ab, cnt_ac, cnt_bc;
map<tuple<int, int, int>, int> cnt_abc;
int res = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (i < 3)
continue;
res += cnt_ab[{a[i - 2], a[i - 1]}];
res += cnt_ac[{a[i - 2], a[i]}];
res += cnt_bc[{a[i - 1], a[i]}];
res -= 3 * cnt_abc[{a[i - 2], a[i - 1], a[i]}];
cnt_ab[{a[i - 2], a[i - 1]}]++;
cnt_ac[{a[i - 2], a[i]}]++;
cnt_bc[{a[i - 1], a[i]}]++;
cnt_abc[{a[i - 2], a[i - 1], a[i]}]++;
}
cout << res << endl;
}
A3.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' // 交互/调试 关
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
const int mod = 998244353;
const int N = 10 + 5e5;
void _();
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
_();
return 0;
}
void _()
{
int n, m;
cin >> n >> m;
int max_w = 0;
for (int i = 0; i < n; i++)
{
int k;
cin >> k;
map<int, bool> has;
while (k--)
{
int x;
cin >> x;
has[x] = 1;
}
int find = 0;
for (int h = 0;; h++)
if (!has[h])
{
max_w = max(max_w, h);
find++;
if (find == 2)
break;
}
}
// bug(max_w);
int res = (m + 1) * max_w;
if (m > max_w)
res = (max_w + 1) * max_w + (max_w + 1 + m) * (m - max_w) / 2;
cout << res << endl;
}