Codeforces Round #572 (Div. 2)

contest链接


A. Keanu Reeves

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

After playing Neo in the legendary "Matrix" trilogy, Keanu Reeves started doubting himself: maybe we really live in virtual reality? To find if this is true, he needs to solve the following problem.

Let's call a string consisting of only zeroes and ones good if it contains different numbers of zeroes and ones. For example, 1, 101, 0000 are good, while 01, 1001, and 111000 are not good.

We are given a string ?s of length ?n consisting of only zeroes and ones. We need to cut ?s into minimal possible number of substrings ?1,?2,…,??s1,s2,…,sk such that all of them are good. More formally, we have to find minimal by number of strings sequence of good strings ?1,?2,…,??s1,s2,…,sk such that their concatenation (joining) equals ?s, i.e. ?1+?2+⋯+??=?s1+s2+⋯+sk=s.

For example, cuttings 110010 into 110 and 010 or into 11 and 0010 are valid, as 110, 010, 11, 0010 are all good, and we can't cut 110010 to the smaller number of substrings as 110010 isn't good itself. At the same time, cutting of 110010 into 1100 and 10 isn't valid as both strings aren't good. Also, cutting of 110010 into 1, 1, 0010 isn't valid, as it isn't minimal, even though all 33 strings are good.

Can you help Keanu? We can show that the solution always exists. If there are multiple optimal answers, print any.

Input

The first line of the input contains a single integer ?n (1≤?≤1001≤n≤100) — the length of the string ?s.

The second line contains the string ?s of length ?n consisting only from zeros and ones.

Output

In the first line, output a single integer ?k (1≤?1≤k) — a minimal number of strings you have cut ?s into.

In the second line, output ?k strings ?1,?2,…,??s1,s2,…,sk separated with spaces. The length of each string has to be positive. Their concatenation has to be equal to ?s and all of them have to be good.

If there are multiple answers, print any.

 

  一开始读错了题意,WA了一次,后来发现求的是最少的分割数量使得分得的两个块的各自「0、1」的数量都不想等,那么假如原式的01数目相等,我们就可以输出第一个,然后再输出后面的全部即可;假如一开始「0、1」数量就不等,就可以直接输出了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define min3(a, b, c) min(a, min(b, c))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 105;
int N, one = 0;
char s[maxN];
int main()
{
    scanf("%d", &N);
    scanf("%s", s + 1);
    for(int i=1; i<=N; i++) one += s[i] == '1';
    if((one << 1) == N)
    {
        printf("2\n");
        printf("%c ", s[1]);
        for(int i=2; i<=N; i++) printf("%c", s[i]);
        printf("\n");
    }
    else
    {
        printf("1\n");
        printf("%s\n", s + 1);
    }
    return 0;
}

 


B. Number Circle

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given ?n numbers ?1,?2,…,??a1,a2,…,an. Is it possible to arrange them in a circle in such a way that every number is strictly less than the sum of its neighbors?

For example, for the array [1,4,5,6,7,8][1,4,5,6,7,8], the arrangement on the left is valid, while arrangement on the right is not, as 5≥4+15≥4+1 and 8>1+68>1+6.

Input

The first line contains a single integer ?n (3≤?≤1053≤n≤105) — the number of numbers.

The second line contains ?n integers ?1,?2,…,??a1,a2,…,an (1≤??≤1091≤ai≤109) — the numbers. The given numbers are not necessarily distinct (i.e. duplicates are allowed).

Output

If there is no solution, output "NO" in the first line.

If there is a solution, output "YES" in the first line. In the second line output ?n numbers — elements of the array in the order they will stay in the circle. The first and the last element you output are considered neighbors in the circle. If there are multiple solutions, output any of them. You can print the circle starting with any element.

 

  比赛的时候我是先写了C,然后再回来写B的,因为一开始的时候B就接连WA了3次,WA6。一个小时的时候,我想了下,发现可以处理出来最大的值a[N],然后我们再去把a[N-1]次大的数放在它的边上,然后再去找有没有一个数,刚好加上a[N-1]的时候大于a[N],然后再把他们两个中间的数排起来即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define min3(a, b, c) min(a, min(b, c))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e5 + 7;
int N, a[maxN], ans[maxN];
int main()
{
    scanf("%d", &N);
    for(int i=1; i<=N; i++) { scanf("%d", &a[i]); }
    sort(a + 1, a + N + 1);
    int ansl = 0, ansr = 0;
    ans[N] = a[N];
    ansr = N - 2;
    ansl = (int)(upper_bound(a + 1, a + N + 1, a[N] - a[N - 1]) - a);
    if(ansl >= N - 1) { printf("NO\n"); return 0; }
    ans[2] = a[N];
    ans[1] = a[N-1];
    for(int i=N; i>=3; i--)
    {
        if(ansl == ansr) break;
        ans[i] = a[ansr--];
    }
    for(int i=3; i<=N; i++)
    {
        if(!ansl) break;
        ans[i] = a[ansl--];
    }
    printf("YES\n");
    for(int i=1; i<=N; i++) printf("%d%c", ans[i], i == N ? '\n' : ' ');
    return 0;
}
 

 


C. Candies!

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Consider a sequence of digits of length 2?2k [?1,?2,…,?2?][a1,a2,…,a2k]. We perform the following operation with it: replace pairs (?2?+1,?2?+2)(a2i+1,a2i+2) with (?2?+1+?2?+2)mod10(a2i+1+a2i+2)mod10 for 0≤?<2?−10≤i<2k−1. For every ?i where ?2?+1+?2?+2≥10a2i+1+a2i+2≥10 we get a candy! As a result, we will get a sequence of length 2?−12k−1.

Less formally, we partition sequence of length 2?2k into 2?−12k−1 pairs, each consisting of 2 numbers: the first pair consists of the first and second numbers, the second of the third and fourth ……, the last pair consists of the (2?−12k−1)-th and (2?2k)-th numbers. For every pair such that sum of numbers in it is at least 1010, we get a candy. After that, we replace every pair of numbers with a remainder of the division of their sum by 1010 (and don't change the order of the numbers).

Perform this operation with a resulting array until it becomes of length 11. Let ?([?1,?2,…,?2?])f([a1,a2,…,a2k]) denote the number of candies we get in this process.

For example: if the starting sequence is [8,7,3,1,7,0,9,4][8,7,3,1,7,0,9,4] then:

After the first operation the sequence becomes [(8+7)mod10,(3+1)mod10,(7+0)mod10,(9+4)mod10][(8+7)mod10,(3+1)mod10,(7+0)mod10,(9+4)mod10] == [5,4,7,3][5,4,7,3], and we get 22 candies as 8+7≥108+7≥10 and 9+4≥109+4≥10.

After the second operation the sequence becomes [(5+4)mod10,(7+3)mod10][(5+4)mod10,(7+3)mod10] == [9,0][9,0], and we get one more candy as 7+3≥107+3≥10.

After the final operation sequence becomes [(9+0)mod10][(9+0)mod10] == [9][9].

Therefore, ?([8,7,3,1,7,0,9,4])=3f([8,7,3,1,7,0,9,4])=3 as we got 33 candies in total.

You are given a sequence of digits of length ?n ?1,?2,…??s1,s2,…sn. You have to answer ?q queries of the form (??,??)(li,ri), where for ?i-th query you have to output ?([???,???+1,…,???])f([sli,sli+1,…,sri]). It is guaranteed that ??−??+1ri−li+1 is of form 2?2k for some nonnegative integer ?k.

Input

The first line contains a single integer ?n (1≤?≤1051≤n≤105) — the length of the sequence.

The second line contains ?n digits ?1,?2,…,??s1,s2,…,sn (0≤??≤90≤si≤9).

The third line contains a single integer ?q (1≤?≤1051≤q≤105) — the number of queries.

Each of the next ?q lines contains two integers ??li, ??ri (1≤??≤??≤?1≤li≤ri≤n) — ?i-th query. It is guaranteed that ??−??+1ri−li+1 is a nonnegative integer power of 22.

Output

Output ?q lines, in ?i-th line output single integer — ?([???,???+1,…,???])f([sli,sli+1,…,sri]), answer to the ?i-th query.

 

  这道题的题意好奇怪,讲了一大堆,后来发现就是问一段区间[l, r]区间和去除以10并且向下取整得到的数。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define min3(a, b, c) min(a, min(b, c))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e5 + 7;
int N, Q;
ll a[maxN], pre[maxN];
int main()
{
    scanf("%d", &N);
    pre[0] = 0;
    for(int i=1; i<=N; i++)
    {
        scanf("%lld", &a[i]);
        pre[i] = pre[i-1] + a[i];
    }
    scanf("%d", &Q);
    while(Q--)
    {
        int l, r; scanf("%d%d", &l, &r);
        printf("%lld\n", (pre[r] - pre[l-1])/10);
    }
    return 0;
}

 


D1. Add on a Tree

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Note that this is the first problem of the two similar problems. You can hack this problem only if you solve both problems.

You are given a tree with ?n nodes. In the beginning, 00 is written on all edges. In one operation, you can choose any 22 distinct leaves ?u, ?vand any real number ?x and add ?x to values written on all edges on the simple path between ?u and ?v.

For example, on the picture below you can see the result of applying two operations to the graph: adding 22 on the path from 77 to 66, and then adding −0.5−0.5 on the path from 44 to 55.

Is it true that for any configuration of real numbers written on edges, we can achieve it with a finite number of operations?

Leaf is a node of a tree of degree 11. Simple path is a path that doesn't contain any node twice.

Input

The first line contains a single integer ?n (2≤?≤1052≤n≤105) — the number of nodes.

Each of the next ?−1n−1 lines contains two integers ?u and ?v (1≤?,?≤?1≤u,v≤n, ?≠?u≠v), meaning that there is an edge between nodes ?u and ?v. It is guaranteed that these edges form a tree.

Output

If there is a configuration of real numbers written on edges of the tree that we can't achieve by performing the operations, output "NO".

Otherwise, output "YES".

You can print each letter in any case (upper or lower).

 

  D1问的就是,我们是否可以使得树上的没条路径的值是可按照自己想法改变为多少都可以的,并且不会影响到其他的路径。那么我们可以看到,假如有度为2的节点,那么改变其中一条相邻的边,另一条也一定会被随之改变。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define min3(a, b, c) min(a, min(b, c))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e5 + 7;
int N, du[maxN];
int main()
{
    scanf("%d", &N);
    for(int i=1, u, v; i<N; i++)
    {
        scanf("%d%d", &u, &v);
        du[u]++;
        du[v]++;
    }
    for(int i=1; i<=N; i++) if(du[i] == 2) { printf("NO\n"); return 0; }
    printf("YES\n");
    return 0;
}

 


D2. Add on a Tree: Revolution

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Note that this is the second problem of the two similar problems. You can hack this problem if you solve it. But you can hack the previous problem only if you solve both problems.

You are given a tree with ?n nodes. In the beginning, 00 is written on all edges. In one operation, you can choose any 22 distinct leaves ?u, ?vand any integer number ?x and add ?x to values written on all edges on the simple path between ?u and ?v. Note that in previous subtask ?x was allowed to be any real, here it has to be integer.

For example, on the picture below you can see the result of applying two operations to the graph: adding 22 on the path from 77 to 66, and then adding −1−1 on the path from 44 to 55.

You are given some configuration of nonnegative integer pairwise different even numbers, written on the edges. For a given configuration determine if it is possible to achieve it with these operations, and, if it is possible, output the sequence of operations that leads to the given configuration. Constraints on the operations are listed in the output format section.

Leave is a node of a tree of degree 11. Simple path is a path that doesn't contain any node twice.

Input

The first line contains a single integer ?n (2≤?≤10002≤n≤1000) — the number of nodes in a tree.

Each of the next ?−1n−1 lines contains three integers ?u, ?v, ???val (1≤?,?≤?1≤u,v≤n, ?≠?u≠v, 0≤???≤100000≤val≤10000), meaning that there is an edge between nodes ?u and ?v with ???val written on it. It is guaranteed that these edges form a tree. It is guaranteed that all ???val numbers are pairwise different and even.

Output

If there aren't any sequences of operations which lead to the given configuration, output "NO".

If it exists, output "YES" in the first line. In the second line output ?m — number of operations you are going to apply (0≤?≤1050≤m≤105). Note that you don't have to minimize the number of the operations!

In the next ?m lines output the operations in the following format:

?,?,?u,v,x (1≤?,?≤?1≤u,v≤n, ?≠?u≠v, ?x — integer, −109≤?≤109−109≤x≤109), where ?,?u,v — leaves, ?x — number we are adding.

It is guaranteed that if there exists a sequence of operations producing given configuration, then there exists a sequence of operations producing given configuration, satisfying all the conditions above.

 

  D2比之D1确实就难了不少,比赛的时候也是没有敲出来,然后补题的时候,也是一直WA2,但是列写一下,发现自己的代码的数据确实是可以过Test 2的,然后我把double去改成int类型再输出,竟然就A了,好神奇……!

  我们可以这样来想这道题,只要满足D1的条件,也就是可以随意改变之后,那么就一定是“YES”了,之后我们需要怎样去改变呢,才能让所有的边都变成我们想要的样子?

  我们要从1~N-1,改变这么多条边,我们可以看到改变“u — v”这条边,如果u、v都是叶子节点的话,那么很简单,只用改变u、v即可;但是如果u、v中u是叶子节点,而v不是呢,我们可以把v向u的反方向(也就是不经过u的方向)去找连个叶子节点(并且是一定可以找到两个叶子节点的,因为度是大于2的),然后假设这两个节点分别为fir和sec,那么我们是不是可以把u—v的边权分成两半“val / 2”(题目中又说到“ all ???val numbers are pairwise”说明说有的val都是可以被2整除的),然后我们这么改变u -- fir去加上val / 2,再v -- sec去加上val / 2,最后fir -- sec去减去val / 2岂不是就可以了。那么,另外最悲催的情况,u、v都不是叶子节点的时候,我们可以效仿刚才的做法,u出发得到的节点两个x1、x2,v出发得到的叶子节点两个y1、y2,然后我们x1 -- y1去加上val / 2,然后x2 -- y2去加上val / 2,最后,x1 -- x2减去val / 2,以及y1 -- y2去减去val / 2即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
#define MP3(a, b, c) MP(MP(a, b), c)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e5 + 7;
int N, du[maxN], head[maxN], cnt;
vector<pair<pair<int, int>, int>> ans;
struct Eddge
{
    int nex, to;
    int val;
    Eddge(int a=-1, int b=0, int c=0):nex(a), to(b), val(c) {}
}edge[maxN<<1];
inline void addEddge(int u, int v, int val)
{
    edge[cnt] = Eddge(head[u], v, val);
    head[u] = cnt++;
}
inline void _add(int u, int v, int val) { addEddge(u, v, val); addEddge(v, u, val); }
pair<pair<int, int>, int> path[maxN];
inline int dfs(int u, int fa)
{
    if(du[u] == 1) return u;
    else
    {
        for(int i=head[u], v; ~i; i=edge[i].nex)
        {
            v = edge[i].to;
            if(v == fa) continue;
            else return dfs(v, u);
        }
    }
    return u;
}
inline void init()
{
    cnt = 0;
    memset(head, -1, sizeof(head));
}
int main()
{
    scanf("%d", &N);
    init();
    for(int i=1, u, v; i<N; i++)
    {
        int w;
        scanf("%d%d%d", &u, &v, &w);
        _add(u, v, w);
        du[u]++; du[v]++;
        path[i] = MP3(u, v, w);
    }
    for(int i=1; i<=N; i++) if(du[i] == 2) { printf("NO\n"); return 0; }
    printf("YES\n");
    for(int i=1, u, v; i<N; i++)
    {
        tie(u, v) = path[i].first;  //u、v就是path[i]的u、v
        pair<int, int> UU = {-1, -1};
        for(int j=head[u], tv; ~j; j=edge[j].nex)
        {
            tv = edge[j].to;
            if(tv == v) continue;
            int tmp = dfs(tv, u);
            if(UU.first == -1) UU.first = tmp;
            else if(UU.second == -1) { UU.second = tmp; break; }
        }
        pair<int, int> VV = {-1, -1};
        for(int j=head[v], tu; ~j; j=edge[j].nex)
        {
            tu = edge[j].to;
            if(tu == u) continue;
            int tmp = dfs(tu, v);
            if(VV.first == -1) VV.first = tmp;
            else if(VV.second == -1) { VV.second = tmp; break; }
        }
        if(du[u] == 1) UU = {u, u};
        if(du[v] == 1) VV = {v, v};
        int real = path[i].second / 2;
        ans.push_back(MP3(UU.first, VV.first, real));
        ans.push_back(MP3(UU.second, VV.second, real));
        if(UU.first != UU.second) ans.push_back(MP3(UU.first, UU.second, -real));
        if(VV.first != VV.second) ans.push_back(MP3(VV.first, VV.second, -real));
    }
    printf("%d\n", (int)ans.size());
    for(int i=0; i<ans.size(); i++) printf("%d %d %d\n", ans[i].first.first, ans[i].first.second, ans[i].second);
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值