Codeforces Round 353 div2
通过数: 2
A:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a, b, c;
while(scanf("%d%d%d", &a, &c, &b) != EOF) {
if((c - a) < 0 && b > 0) printf("NO\n");
else if((c - a) > 0 && b < 0) printf("NO\n");
else if(b == 0) {
if(a == c) printf("YES\n");
else printf("NO\n");
}
else if((c - a) % b == 0) printf("YES\n");
else printf("NO\n");
}
return 0;
}
B:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
int main()
{
int n, a, b, c, d;
while(scanf("%d%d%d%d%d", &n, &a, &b, &c, &d) != EOF) {
int mmin = 1, mmax = n;
mmin = max(mmin, 1 + c - b);
mmin = max(mmin, 1 + d - a);
mmin = max(mmin, 1 + d - a + c - b);
mmin = max(mmin, 1 + d - a + c - b + a - d);
mmax = min(mmax, n + c - b);
mmax = min(mmax, n + d - a);
mmax = min(mmax, n + d - a + c - b);
mmax = min(mmax, n + d - a + c - b + a - d);
long long len = max(mmax - mmin + 1, 0);
printf("%I64d\n", len * n);
}
return 0;
}
C:
/*
对整个数组实现尽可能多的分组,答案为(n-组数)
因此求前缀和
若sum[j] == sum[i],则说明[i,j]可以形成一个单独分组
那么假设从前遍历至最后,sum[k] = val出现了cnt次
则此时前缀和后缀形成一个分组,中间有cnt - 1个分组
则此时答案为n - cnt
*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
map<LL,int>cnt;
int main()
{
int n;
LL sum = 0;
scanf("%d", &n);
int ans = n;
cnt.clear();
for(int i = 1 ; i <= n ; i++) {
int u;
scanf("%d", &u);
sum += u;
cnt[sum]++;
ans = min(ans, n - cnt[sum]);
}
printf("%d", ans);
return 0;
}
D:
/*
根据BST的性质做题
假设当前已经形成了一定子树,设之前插入的点形成有序数组array[i]
则当前插入数的位置k,一定有a[i] > array[k - 1] && a[i] < array[k]
先假设array[k-1]和array[k]有公共祖先,但是此公共祖先lca有array[k-1]<lca<array[k],不合题意
则k-1和k一定为祖先和儿子的关系,他们要么k-1有右儿子,要么k有左儿子
完毕
*/
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
typedef pair<int,int> pii;
const int MAXN = 100000 + 5;
int a[MAXN], n;
set<int>S, lson, rson;
int main()
{
while(scanf("%d", &n) != EOF) {
for(int i = 1 ; i <= n ; i++) scanf("%d", a + i);
S.clear();
lson.clear(), rson.clear();
S.insert(a[1]);
for(int i = 2 ; i <= n ; i++) {
auto it = S.upper_bound(a[i]);
int res;
if(it != S.end() && lson.count(*it) == 0) {
res = *it;
lson.insert(*it);
}
else {
it--; res = *it;
rson.insert(*it);
}
printf("%d%s", res, i == n ? "\n" : " ");
S.insert(a[i]);
}
}
return 0;
}
E:
/*
dp[i] = dp[j] + (n - i) - (a[i] - j)
j是[i+1,a[i]]区间内a[j]最大的一个。由于a[a[i]] >= a[i] + 1,故最大值大于a[i]
*/
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define fi first
#define se second
typedef pair<int,int> pii;
const int MAXN = 100000 + 5;
int n, a[MAXN];
pii dp[MAXN * 4];
void pushup(int o){dp[o] = max(dp[(o << 1) | 1], dp[o << 1]);}
void build(int o, int l,int r)
{
if(l == r) {
dp[o] = mp(a[l], l);
}
else {
int mid = (l + r) >> 1;
build(o << 1, l, mid);
build((o << 1) | 1, mid + 1, r);
pushup(o);
}
}
pii query(int o, int l, int r, int L, int R)
{
if(R == n) return mp(-1, n);
if(l >= L && r <= R) return dp[o];
else {
int mid = (l + r) >> 1;
pii res = mp(-2, 0);
if(mid >= L) res = max(res, query(o << 1, l, mid , L, R));
if(mid < R) res = max(res, query((o << 1) | 1, mid + 1, r, L, R));
return res;
}
}
long long re[MAXN];
int main()
{
while(scanf("%d", &n) != EOF) {
for(int i = 1 ; i < n ; i++) scanf("%d", a + i);
build(1, 1, n - 1);
long long res = 0;
re[n] = 0;
for(int i = n - 1 ; i >= 1 ; i--) {
if(i == n - 1) {
re[n - 1] = 1;
continue;
}
pii p = query(1, 1, n - 1, i + 1, a[i]);
int mark = p.se;
re[i] = re[mark] - (a[i] - mark) + n - i;
// if(a[i] >= n) re[i] = min(re[i], (long long)n - i);
// printf("i = %d, mark = %d, re[i] = %d\n", i, mark, re[i]);
res += re[i];
}
printf("%I64d\n", res + 1);
}
return 0;
}