Manthan, Codefest 18 (rated, Div. 1 + Div. 2) ABCDE

A. Packets

You have nn coins, each of the same value of 11.

Distribute them into packets such that any amount xx (1xn1≤x≤n) can be formed using some (possibly one or all) number of these packets.

Each packet may only be used entirely or not used at all. No packet may be used more than once in the formation of the single xx, however it may be reused for the formation of other xx's.

Find the minimum number of packets in such a distribution.

Input

The only line contains a single integer nn (1n1091≤n≤109) — the number of coins you have.

Output

Output a single integer — the minimum possible number of packets, satisfying the condition above.

Examples
input
Copy
6
output
Copy
3
input
Copy
2
output
Copy
2
Note

In the first example, three packets with 11, 22 and 33 coins can be made to get any amount xx (1x61≤x≤6).

  • To get 11 use the packet with 11 coin.
  • To get 22 use the packet with 22 coins.
  • To get 33 use the packet with 33 coins.
  • To get 44 use packets with 11 and 33 coins.
  • To get 55 use packets with 22 and 33 coins
  • To get 66 use all packets.

In the second example, two packets with 11 and 11 coins can be made to get any amount xx (1x21≤x≤2).

将n最少分成多少个数,使的1-n 都可以由这些数组成。  看成二进制,分成1 10 100 1000...就行。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define INF 0x3f3f3f3f
 4 using namespace std;
 5 
 6 int main() {
 7     int n;
 8     cin >> n;
 9     printf("%d\n",(int)log2(n)+1);
10     return 0;
11 }

B. Reach Median

You are given an array aa of nn integers and an integer ss. It is guaranteed that nn is odd.

In one operation you can either increase or decrease any single element by one. Calculate the minimum number of operations required to make the median of the array being equal to ss.

The median of the array with odd length is the value of the element which is located on the middle position after the array is sorted. For example, the median of the array 6,5,86,5,8 is equal to 66, since if we sort this array we will get 5,6,85,6,8, and 66 is located on the middle position.

Input

The first line contains two integers nn and ss (1n210511≤n≤2⋅105−1, 1s1091≤s≤109) — the length of the array and the required value of median.

The second line contains nn integers a1,a2,,ana1,a2,…,an (1ai1091≤ai≤109) — the elements of the array aa.

It is guaranteed that nn is odd.

Output

In a single line output the minimum number of operations to make the median being equal to ss.

Examples
input
Copy
3 8
6 5 8
output
Copy
2
input
Copy
7 20
21 15 12 11 20 19 12
output
Copy
6
Note

In the first sample, 66 can be increased twice. The array will transform to 8,5,88,5,8, which becomes 5,8,85,8,8 after sorting, hence the median is equal to 88.

In the second sample, 1919 can be increased once and 1515 can be increased five times. The array will become equal to 21,20,12,11,20,20,1221,20,12,11,20,20,12. If we sort this array we get 11,12,12,20,20,20,2111,12,12,20,20,20,21, this way the median is 2020.

将中位数变成s,排序后看最中间的数是多少,然后调整其它数字为s。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 2e5+10;
 5 ll a[N];
 6 int main() {
 7     ll n, s;
 8     cin >> n >> s;
 9     for(int i = 1; i <= n; i ++) cin >> a[i];
10     sort(a+1,a+1+n);
11     ll ans = 0;
12     if(a[n/2+1] < s) {
13         for(int i = n/2+1; i <= n; i ++) {
14             if(a[i] < s) ans += s-a[i];
15         }
16     } else {
17         for(int i = n/2+1; i >= 1; -- i) {
18             if(a[i] > s) ans += a[i] - s;
19         }
20     }
21     printf("%lld\n",ans);
22     return 0;
23 }

C. Equalize

You are given two binary strings aa and bb of the same length. You can perform the following two operations on the string aa:

  • Swap any two bits at indices ii and jj respectively (1i,jn1≤i,j≤n), the cost of this operation is |ij||i−j|, that is, the absolute difference between ii and jj.
  • Select any arbitrary index ii (1in1≤i≤n) and flip (change 00 to 11 or 11 to 00) the bit at this index. The cost of this operation is 11.

Find the minimum cost to make the string aa equal to bb. It is not allowed to modify string bb.

Input

The first line contains a single integer nn (1n1061≤n≤106) — the length of the strings aa and bb.

The second and third lines contain strings aa and bb respectively.

Both strings aa and bb have length nn and contain only '0' and '1'.

Output

Output the minimum cost to make the string aa equal to bb.

Examples
input
Copy
3
100
001
output
Copy
2
input
Copy
4
0101
0011
output
Copy
1
Note

In the first example, one of the optimal solutions is to flip index 11 and index 33, the string aa changes in the following way: "100" → "000" →"001". The cost is 1+1=21+1=2.

The other optimal solution is to swap bits and indices 11 and 33, the string aa changes then "100" → "001", the cost is also |13|=2|1−3|=2.

In the second example, the optimal solution is to swap bits at indices 22 and 33, the string aa changes as "0101" → "0011". The cost is |23|=1|2−3|=1.

只有当连续两个位置都不同,且同一字符串中也不同是选择交换更好,其它都直接改变数字。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e6+10;
 4 char s1[N], s2[N];
 5 int main() {
 6     int n;
 7     cin >> n >> s1 >> s2;
 8     int ans = 0;
 9     for(int i = 0; i < n; i ++) {
10         if(s1[i] != s2[i]) {
11             if(i+1 < n && s1[i+1] != s2[i+1] && s1[i] != s1[i+1]) {
12                 s1[i+1] = s2[i+1];
13             }
14             ans++;
15         }
16     }
17     printf("%d\n",ans);
18     return 0;
19 }

D. Valid BFS?

The BFS algorithm is defined as follows.

  1. Consider an undirected graph with vertices numbered from 11 to nn. Initialize qq as a new queue containing only vertex 11, mark the vertex 11 as used.
  2. Extract a vertex vv from the head of the queue qq.
  3. Print the index of vertex vv.
  4. Iterate in arbitrary order through all such vertices uu that uu is a neighbor of vv and is not marked yet as used. Mark the vertex uu as used and insert it into the tail of the queue qq.
  5. If the queue is not empty, continue from step 2.
  6. Otherwise finish.

Since the order of choosing neighbors of each vertex can vary, it turns out that there may be multiple sequences which BFS can print.

In this problem you need to check whether a given sequence corresponds to some valid BFS traversal of the given tree starting from vertex 11. The tree is an undirected graph, such that there is exactly one simple path between any two vertices.

Input

The first line contains a single integer nn (1n21051≤n≤2⋅105) which denotes the number of nodes in the tree.

The following n1n−1 lines describe the edges of the tree. Each of them contains two integers xx and yy (1x,yn1≤x,y≤n) — the endpoints of the corresponding edge of the tree. It is guaranteed that the given graph is a tree.

The last line contains nn distinct integers a1,a2,,ana1,a2,…,an (1ain1≤ai≤n) — the sequence to check.

Output

Print "Yes" (quotes for clarity) if the sequence corresponds to some valid BFS traversal of the given tree and "No" (quotes for clarity) otherwise.

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

Examples
input
Copy
4
1 2
1 3
2 4
1 2 3 4
output
Copy
Yes
input
Copy
4
1 2
1 3
2 4
1 2 4 3
output
Copy
No
Note

Both sample tests have the same tree in them.

In this tree, there are two valid BFS orderings:

  • 1,2,3,41,2,3,4,
  • 1,3,2,41,3,2,4.

The ordering 1,2,4,31,2,4,3 doesn't correspond to any valid BFS order.

先根据已知的树,计算每个点的层数,然后根据给定的序列,看能不能bfs输出。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5+10;
 4 vector<int> vs[N];
 5 map<int,int> mp[N];
 6 int a[N], d[N];
 7 int main() {
 8     int n, x, y;
 9     cin >> n;
10     for(int i = 1; i < n; i ++) {
11         cin >> x >> y;
12         vs[x].push_back(y);
13         vs[y].push_back(x);
14         mp[x][y] = mp[y][x] = 1;
15     }
16     for(int i = 1; i <= n; i ++) cin >> a[i];
17     d[1] = 1;
18     queue<int> que;
19     que.push(1);
20     while(que.size()) {
21         int v = que.front(); que.pop();
22         for(auto u : vs[v]) {
23             if(d[u] == 0) {
24                 d[u] = d[v] + 1;
25                 que.push(u);
26             }
27         }
28     }
29     // for(int i = 1; i <= n; i ++) printf("%d ",d[i]);printf("\n");
30     for(int i = 1; i < n; i ++) {
31         if(d[a[i]] > d[a[i+1]]) return 0*printf("No\n");
32     }
33     int l = 2;
34     que.push(1);
35     while(que.size()) {
36         int v = que.front(); que.pop();
37         while(l <= n) {
38             if(mp[v].count(a[l])) {
39                 que.push(a[l]); l ++;
40             } else break;
41         }
42     }
43     if(l == n+1) printf("Yes\n");
44     else printf("No\n");
45     return 0;
46 }

E. Trips

There are nn persons who initially don't know each other. On each morning, two of them, who were not friends before, become friends.

We want to plan a trip for every evening of mm days. On each trip, you have to select a group of people that will go on the trip. For every person, one of the following should hold:

  • Either this person does not go on the trip,
  • Or at least kk of his friends also go on the trip.

Note that the friendship is not transitive. That is, if aa and bb are friends and bb and cc are friends, it does not necessarily imply that aa and cc are friends.

For each day, find the maximum number of people that can go on the trip on that day.

Input

The first line contains three integers nn, mm, and kk (2n2105,1m21052≤n≤2⋅105,1≤m≤2⋅105, 1k<n1≤k<n) — the number of people, the number of days and the number of friends each person on the trip should have in the group.

The ii-th (1im1≤i≤m) of the next mm lines contains two integers xx and yy (1x,yn1≤x,y≤n, xyx≠y), meaning that persons xx and yy become friends on the morning of day ii. It is guaranteed that xx and yy were not friends before.

Output

Print exactly mm lines, where the ii-th of them (1im1≤i≤m) contains the maximum number of people that can go on the trip on the evening of the day ii.

Examples
input
Copy
4 4 2
2 3
1 2
1 3
1 4
output
Copy
0
0
3
3
input
Copy
5 8 2
2 1
4 2
5 4
5 2
4 3
5 1
4 1
3 2
output
Copy
0
0
0
3
3
4
4
5
input
Copy
5 7 2
1 5
3 2
2 5
3 4
1 2
5 3
1 3
output
Copy
0
0
0
0
3
4
4
Note

In the first example,

  • 1,2,31,2,3 can go on day 33 and 44.

In the second example,

  • 2,4,52,4,5 can go on day 44 and 55.
  • 1,2,4,51,2,4,5 can go on day 66 and 77.
  • 1,2,3,4,51,2,3,4,5 can go on day 88.

In the third example,

  • 1,2,51,2,5 can go on day 55.
  • 1,2,3,51,2,3,5 can go on day 66 and 77.

这解题思想真巧妙,离线处理,每拆除一堆朋友关系,然后把朋友小于k的点去除,就可以得到答案。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5+10;
 4 set<int> st[N], s;
 5 int ans[N], x[N], y[N];
 6 int n, m, k;
 7 void dfs(int v) {
 8     if(st[v].size() >= k || !s.count(v)) return;
 9     s.erase(v);
10     for(auto u:st[v]) {
11         st[u].erase(v);
12         if(s.count(u) && st[u].size() < k) {
13             dfs(u);
14         }
15     }
16 }
17 
18 int main() {
19     scanf("%d%d%d", &n, &m, &k);
20     for(int i = 1; i <= m; i ++) {
21         scanf("%d%d", &x[i], &y[i]);
22         st[x[i]].insert(y[i]);
23         st[y[i]].insert(x[i]);
24     }
25     for(int i = 1; i <= n; ++ i) s.insert(i);
26     for(int i = 1; i <= n; i ++) {
27         if(st[i].size() < k) {
28             dfs(i);
29         }
30     }
31     ans[m] = s.size();
32     for(int i = m; i > 1; i --) {
33         st[x[i]].erase(y[i]);
34         st[y[i]].erase(x[i]);
35         if(st[x[i]].size() < k) dfs(x[i]);
36         if(st[y[i]].size() < k) dfs(y[i]);
37         ans[i-1] = s.size();
38     }
39     for(int i = 1; i <= m; i ++) printf("%d\n",ans[i]);
40     return 0;
41 }

 

posted @ 2018-09-04 21:11  starry_sky  阅读(186)  评论(0编辑  收藏  举报