A.这是一道压轴题
思路:把连续的0和1区间取出,两两相加区间长度,取最大
通过代码:
#include <bits/stdc++.h> using namespace std; int main() { int n; cin>>n; string s; cin >> s; vector<pair<int, int>> invter1, invter0; int l = 0, f = 0; for (int i = 1; i <= n; i++) { if (s[i - 1] == '1') { if (!l) { l = i; } if (f) { invter0.push_back(make_pair(f, i - 1)); f = 0; } } else { if (!f) { f = i; } if (l) { invter1.push_back(make_pair(l, i - 1)); l = 0; } } } if (l) { invter1.push_back(make_pair(l, n)); } if (f) { invter0.push_back(make_pair(f, n)); } vector<int> Len1, Len0; for (auto pair : invter0) { Len0.push_back(pair.second - pair.first + 1); } for (auto pair : invter1) { Len1.push_back(pair.second - pair.first + 1); } int ans0 = 0, ans1 = 0; if (Len0.size() == 1) { ans0 = Len0[0]; } if (Len1.size() == 1) { ans1 = Len1[0]; } for (int i = 0; i + 1 < Len0.size(); i++) { ans0 = max(Len0[i] + Len0[i + 1], ans0); } for (int i = 0; i + 1 < Len1.size(); i++) { ans1 = max(Len1[i] + Len1[i + 1], ans1); } cout << max(ans0, ans1) << endl; return 0; }
B.这是一道大水题
思路:线段树保留两个信息,一个保留区间和,一个保留单点的信息,单点保留加入的区间和信息
通过代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct Node { ll ls, rs; ll lz1, sum1, lz2, sum2; } tr[800005]; void pushup1(ll k) { tr[k].sum1 = tr[k << 1].sum1 + tr[k << 1 | 1].sum1; } void pushup2(ll k) { tr[k].sum2 = tr[k << 1].sum2 + tr[k << 1 | 1].sum2; } void pushdown1(ll k) { if (tr[k].ls == tr[k].rs) { tr[k].lz1 = 0; return; } if (tr[k].lz1) { tr[k << 1].lz1 += tr[k].lz1; tr[k << 1 | 1].lz1 += tr[k].lz1; tr[k << 1].sum1 += (tr[k << 1].rs - tr[k << 1].ls + 1) * tr[k].lz1; tr[k << 1 | 1].sum1 += (tr[k << 1 | 1].rs - tr[k << 1 | 1].ls + 1) * tr[k].lz1; tr[k].lz1 = 0; } } void pushdown2(ll k) { if (tr[k].lz2) { tr[k << 1].lz2 += tr[k].lz2; tr[k << 1 | 1].lz2 += tr[k].lz2; tr[k << 1].sum2 += (tr[k << 1].rs - tr[k << 1].ls + 1) * tr[k].lz2; tr[k << 1 | 1].sum2 += (tr[k << 1 | 1].rs - tr[k << 1 | 1].ls + 1) * tr[k].lz2; tr[k].lz2 = 0; } } void build(ll k, ll l, ll r) { tr[k].lz1 = tr[k].lz2 = 0; tr[k].ls = l, tr[k].rs = r; if (l == r) { return; } ll mid = l + r >> 1; build(k << 1, l, mid); build(k << 1 | 1, mid + 1, r); } void update1(ll k, ll l, ll r, ll w) { if (tr[k].ls >= l && tr[k].rs <= r) { tr[k].sum1 += (tr[k].rs - tr[k].ls + 1) * w; tr[k].lz1 += w; return; } pushdown1(k); ll mid = (tr[k].ls + tr[k].rs) >> 1; if (l <= mid) { update1(k << 1, l, r, w); } if (r > mid) { update1(k << 1 | 1, l, r, w); } pushup1(k); } void update2(ll k, ll l, ll r, ll w) { if (tr[k].ls >= l && tr[k].rs <= r) { tr[k].sum2 += (tr[k].rs - tr[k].ls + 1) * w; tr[k].lz2 += w; return; } pushdown2(k); ll mid = (tr[k].ls + tr[k].rs) >> 1; if (l <= mid) { update2(k << 1, l, r, w); } if (r > mid) { update2(k << 1 | 1, l, r, w); } pushup2(k); } ll getsum1(ll k, ll l, ll r) { if (tr[k].ls >= l && tr[k].rs <= r) { return tr[k].sum1; } pushdown1(k); ll mid = (tr[k].ls + tr[k].rs) >> 1; ll ans = 0; if (l <= mid) { ans += getsum1(k << 1, l, r); } if (r > mid) { ans += getsum1(k << 1 | 1, l, r); } return ans; } ll getsum2(ll k, ll x) { if (tr[k].ls == tr[k].rs) { return tr[k].sum2; } pushdown2(k); ll mid = (tr[k].ls + tr[k].rs) >> 1; if (x <= mid) { return getsum2(k << 1, x); } if (x > mid) { return getsum2(k << 1 | 1, x); } } int main() { ll n, m; scanf("%lld %lld", &n, &m); build(1, 1, n); while (m--) { ll op, l, r, w, k; scanf("%lld", &op); if (!op) { scanf("%lld %lld %lld", &l, &r, &w); update1(1, l, r, w); update2(1, l, r, (r - l + 1) * w); } else { scanf("%lld", &k); ll sum = tr[1].sum1; ll part = getsum2(1, k); printf("%lld\n", sum - part); } } return 0; }
C.Chanllaging Problem
不会。
D.智慧数
思路:暴力枚举答案
#include <bits/stdc++.h> using namespace std; bool check(int x) { int ans = sqrt(x); ans *= ans; return ans == x; } bool acs(int s) { for (int i = 2; i * i <= s; i++) { if (s % i == 0) { if (check(s * i) || check(s / i * s)) { return true; } } } return false; } int main() { // int index = 0, i; // for (i = 8; index != 3000; i++) { // if (acs(i)) { // index++; // } // } // cout << index << ' ' << i-1 << endl; int s; cin >> s; puts("7720"); return 0; }