A.这是一道压轴题
思路:把连续的0和1区间取出,两两相加区间长度,取最大
通过代码:
#include
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
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
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;
}