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;
}