AIM Tech Round 3 (Div. 2)(题解)

比赛题目(传送门)


A. Juicer

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

Kolya is going to make fresh orange juice. He has n oranges of sizes a 1   , a 2   , …, a n   . Kolya will put them in the juicer in the fixed order, starting with orange of size a 1   , then orange of size a 2   and so on. To be put in the juicer the orange must have size not exceeding b, so if Kolya sees an orange that is strictly greater he throws it away and continues with the next one.

The juicer has a special section to collect waste. It overflows if Kolya squeezes oranges of the total size strictly greater than d  . When it happens Kolya empties the waste section (even if there are no more oranges) and continues to squeeze the juice. How many times will he have to empty the waste section?

Input

The first line of the input contains three integers n , b  and d(1n100000,1bd1000000)  — the number of oranges, the maximum size of the orange that fits in the juicer and the value d, which determines the condition when the waste section should be emptied.

The second line contains n  integers a 1 ,a 2 ,...,a n (1a i 1000000)  — sizes of the oranges listed in the order Kolya is going to try to put them in the juicer.

Output

Print one integer — the number of times Kolya will have to empty the waste section.

Examples

input
2 7 10
5 6
output
1
input
1 5 10
7
output
0
input
3 10 10
5 7 7
output
1
input
1 1 1
1
output
0

Note

In the first sample, Kolya will squeeze the juice from two oranges and empty the waste section afterwards.

In the second sample, the orange won’t fit in the juicer so Kolya will have no juice at all.

题意

给你 n  个橙子,要选小于等于b 的橙子做成果汁,如果放进果汁机的橙总和大于 d  ,就将果汁机里的东西全部都去掉即浪费一次。问你把这些橙全部做成果汁的过程中共浪费了多少次?

解题思路:模拟

创建变量res ,直接从头到尾,不断将大小小于等于 b  的橙子放进果汁机中,然后判断是否大于d ,如果大于则 res  1  . [ 记得用大数 ] 

代码

时间复杂度:O(n) 

/*头文件模板*/

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

#define pb push_back
#define mp make_pair
#define mem(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a))
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)

typedef long long LL;
typedef pair<int, int > PII;
typedef pair<int, string> PIS;
typedef pair<LL, LL>PLL;
typedef unsigned long long uLL;

template<typename T>
void print (T* p, T* q, string Gap = " ", bool flag = false) {
    int d = p < q ? 1 : -1;
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
}

template<typename T>
void print (const T &a, string bes = "") {
    int len = bes.length();
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
}

template<typename T>
void debug (T* p, T* q, string Gap = " ", bool flag = false) {
#ifndef ONLINE_JUDGE
    int d = p < q ? 1 : -1;
    cout << "Debug out : ";
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
#endif
}

template<typename T>
void debug (const T &a, string bes = "") {
#ifndef ONLINE_JUDGE
    int len = bes.length();
    cout << "Debug out : ";
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
#endif
}

void IO_Init() {
    ios::sync_with_stdio (false);
}

LL LLabs (const LL a) {
    return a >= 0 ? a : -a;
}

const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 1e5 + 5;
const int INF = 0x3f3f3f3f;

/*头文件模板*/

LL n, b, d;

int main() {
#ifndef ONLINE_JUDGE
    //FIN;
    //FOUT;
#endif
    IO_Init();
    while(~scanf("%lld%lld%lld", &n, &b, &d)){
        LL x, sum = 0, num = 0;
        for(int i = 0;i <  n;i ++){
            scanf("%lld", &x);
            if(x > b) continue;
            sum += x;
            if(sum > d) sum = 0, num ++;
        }
        printf("%lld\n", num);
    }


    return 0;
}

B. Checkpoints

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

Vasya takes part in the orienteering competition. There are n  checkpoints located along the line at coordinates x 1 ,x 2 ,...,x n  . Vasya starts at the point with coordinate a. His goal is to visit at least n1  checkpoint in order to finish the competition. Participant are allowed to visit checkpoints in arbitrary order.

Vasya wants to pick such checkpoints and the order of visiting them that the total distance travelled is minimized. He asks you to calculate this minimum possible value.

Input

The first line of the input contains two integers n  and a(1n100000,1000000a1000000)  — the number of checkpoints and Vasya’s starting position respectively.

The second line contains n  integers x 1 ,x 2 ,...,x n (1000000x i 1000000)  — coordinates of the checkpoints.

Output

Print one integer — the minimum distance Vasya has to travel in order to visit at least n1  checkpoint.

Examples

input
3 10
1 7 12
output
7
input
2 0
11 -10
output
10
input
5 0
0 0 1000 0 0
output
0

Note

In the first sample Vasya has to visit at least two checkpoints. The optimal way to achieve this is the walk to the third checkpoints (distance is 1210=2  ) and then proceed to the second one (distance is 127=5  ). The total distance is equal to 2+5=7  .

In the second sample it’s enough to visit only one checkpoint so Vasya should just walk to the point   10  .

题意

给你 n  个点,要经过n1 个点才算完成比赛,问完成比赛的最小路程是多少?

解题思路:模拟

有题目可以知道,总共点就只有 n  个,而我要走遍n1 个点.

如此,就只存在四种情况:

  1. 从当前位置到达最右边的点 x n   ,然后回到第二个点的位置 x 2   ,经历了 n1  个点

  2. 从当前位置到达最右边倒数第二个点 x n1   ,然后回到第一个点的位置 x 1   ,经历了 n1  个点

  3. 从当前位置到达最左边的点 x 1   ,然后回到最右边倒数第二个点的位置 x n1   ,经历了 n1  个点

  4. 从当前位置到达最左边的点 x 2   ,然后回到最右边倒数第二个点的位置 x n   ,经历了 n1  个点

取这四种情况的最小值即是答案. [  注意大数,同时要注意最开始的点可能在所有点的右边,也可能在所有点的左边,所以有些部分要取绝对值 ] 

代码

时间复杂度: O(n) 

/*头文件模板*/

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

#define pb push_back
#define mp make_pair
#define mem(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a))
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)

typedef long long LL;
typedef pair<int, int > PII;
typedef pair<int, string> PIS;
typedef pair<LL, LL>PLL;
typedef unsigned long long uLL;

template<typename T>
void print (T* p, T* q, string Gap = " ", bool flag = false) {
    int d = p < q ? 1 : -1;
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
}

template<typename T>
void print (const T &a, string bes = "") {
    int len = bes.length();
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
}

template<typename T>
void debug (T* p, T* q, string Gap = " ", bool flag = false) {
#ifndef ONLINE_JUDGE
    int d = p < q ? 1 : -1;
    cout << "Debug out : ";
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
#endif
}

template<typename T>
void debug (const T &a, string bes = "") {
#ifndef ONLINE_JUDGE
    int len = bes.length();
    cout << "Debug out : ";
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
#endif
}

void IO_Init() {
    ios::sync_with_stdio (false);
}

LL LLabs (const LL a) {
    return a >= 0 ? a : -a;
}

const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 1e5 + 5;
const int INF = 0x3f3f3f3f;

/*头文件模板*/

LL n, a;
LL A[MAXN];
int main() {
#ifndef ONLINE_JUDGE
    //FIN;
    //FOUT;
#endif
    IO_Init();
    while(~scanf("%lld%lld", &n, &a)) {
        for(int i = 0; i < n; i ++) {
            scanf("%lld", &A[i]);
        }
        if(n == 1){
            puts("0");
            continue;
        }
        sort(A, A + n);
        LL a1 = abs(A[n - 1] - a) + A[n - 1] - A[1];
        LL a2 = abs(A[n - 2] - a) + A[n - 2] - A[0];
        LL a3 = abs(a - A[1]) + A[n - 1] - A[1];
        LL a4 = abs(a - A[0]) + A[n - 2] - A[0];
        printf("%lld\n", min(a1, min(a2, min(a3, a4))));
    }
    return 0;
}

C. Letters Cyclic Shift

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

You are given a non-empty string s  consisting of lowercase English letters. You have to pick exactly one non-empty substring of s  and shift all its letters ‘ z    y ’ ‘ x  ’ ‘b ’ ‘ a  ’ ‘z ’. In other words, each character is replaced with the previous character of English alphabet and ‘ a  ’ is replaced with ‘z ’.

What is the lexicographically minimum string that can be obtained from s by performing this shift exactly once?

Input

The only line of the input contains the string s(1|s|100000)  consisting of lowercase English letters.

Output

Print the lexicographically minimum string that can be obtained from s  by shifting letters of exactly one non-empty substring.

Examples

input
codeforces
output
bncdenqbdr
input
abacaba
output
aaacaba

Note

String s  is lexicographically smaller than some other string t of the same length if there exists some 1i|s|  , such that s 1 =t 1 ,s 2 =t 2 ,...,s i 1=t i 1  , and s i <t i   .

题意

给定一个字符串 s  ,让你进行有且仅有一次的改变:将这个字符串中的某个子串的每一个字符向前更变即’b ’变为’ a  ’,’c ’变为’ b  ... ,’ a  ’变为’z ’.输出这个字符串进行一次变化后字典序最小的字符串.

解题思路:模拟

分两种情况:

  1. 如果不是全部是 a  ,就找到第一个不是a 的子串 sub  ,将它全部变化

  2. 如果全部是 a  ,最后一个a 就变成 z 

代码

时间复杂度:O(n) 

/*头文件模板*/

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

#define pb push_back
#define mp make_pair
#define mem(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a))
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)

typedef long long LL;
typedef pair<int, int > PII;
typedef pair<int, string> PIS;
typedef pair<LL, LL>PLL;
typedef unsigned long long uLL;

template<typename T>
void print (T* p, T* q, string Gap = " ", bool flag = false) {
    int d = p < q ? 1 : -1;
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
}

template<typename T>
void print (const T &a, string bes = "") {
    int len = bes.length();
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
}

template<typename T>
void debug (T* p, T* q, string Gap = " ", bool flag = false) {
#ifndef ONLINE_JUDGE
    int d = p < q ? 1 : -1;
    cout << "Debug out : ";
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
#endif
}

template<typename T>
void debug (const T &a, string bes = "") {
#ifndef ONLINE_JUDGE
    int len = bes.length();
    cout << "Debug out : ";
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
#endif
}

void IO_Init() {
    ios::sync_with_stdio (false);
}

LL LLabs (const LL a) {
    return a >= 0 ? a : -a;
}

const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 1e5 + 5;
const int INF = 0x3f3f3f3f;

/*头文件模板*/

char A[MAXN];

int main() {
#ifndef ONLINE_JUDGE
    //FIN;
    //FOUT;
#endif
    IO_Init();
    while(~scanf("%s", A)) {
        int l = -1, r = -1, len = strlen(A);
        for(int i = 0; i < len; i ++) {
            if(A[i] != 'a' && l == -1) {
                l = i;
                continue;
            }
            if(l != -1 && A[i] == 'a') {
                r = i;
                break;
            }
        }
        if(r == -1) r = len;
        if(l == -1) l = len - 1;
        for(int i = 0; i < len; i ++) {
            if(i >= l && i < r) {
                char a = A[i] - 1;
                if(a < 'a') a = 'z';
                printf("%c", a);
            } else printf("%c", A[i]);
        }
        printf("\n");
    }
    return 0;
}

D. Recover the String

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

For each string s  consisting of characters ‘0 ’ and ‘ 1  ’ one can define four integers a 00  , a 01   , a 10   and a 11   , where axy is the number of subsequences of length 2  of the string s  equal to the sequence {x,y}  .

In these problem you are given four integers a 00   , a 01   , a 10   , a 11   and have to find any non-empty string s  that matches them, or determine that there is no such string. One can prove that if at least one answer exists, there exists an answer of length no more than 1000000 .

Input

The only line of the input contains four non-negative integers a 00   , a 01   , a 10   and a 11   . Each of them doesn’t exceed 10 9   .

Output

If there exists a non-empty string that matches four integers from the input, print it in the only line of the output. Otherwise, print “ Impossible  ”. The length of your answer must not exceed 1000000  .

Examples

input
1 2 3 4
output
Impossible
input
1 2 2 1
output
0110

题意

给你 00,01,10,11  这四个序列每一个的个数。然后要你构造出一个合法的 01  序列。不存在合法的 01  序列就输出 Impossible 

解题思路:模拟

通过 00  11  的个数,我们可以得到他们和 01  , 10  个数关系:

(1  的个数 )×(0  的个数 )=(10  的个数 )+  (01  的个数 ) 

而求解前两者的方法 等加数列求和

我们设 n  m  0  的个数和1 的个数,存在几个等式成立:

nm=a 01 +a 10  

n(n1)=2a 00  

m(m1)=2a 11  

如果不满足上述条件则直接输出 Impossible  .其它情况证明存在一个序列满足条件.

接下来就是构造字符串的方法:

针对当前位置,如果放 0  的话,将增加01 串的个数为当前剩余的 1  的个数,同等放1 的结论类似,一直这样下去即可

代码

时间复杂度: O(K)  [  K 值结果有点悬 ] 

/*头文件模板*/

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>
#include <windows.h>

using namespace std;

#define pb push_back
#define mp make_pair
#define mem(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a))
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)

typedef long long LL;
typedef pair<int, int > PII;
typedef pair<int, string> PIS;
typedef pair<LL, LL>PLL;
typedef unsigned long long uLL;

template<typename T>
void print (T* p, T* q, string Gap = " ", bool flag = false) {
    int d = p < q ? 1 : -1;
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
}

template<typename T>
void print (const T &a, string bes = "") {
    int len = bes.length();
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
}

template<typename T>
void debug (T* p, T* q, string Gap = " ", bool flag = false) {
#ifndef ONLINE_JUDGE
    int d = p < q ? 1 : -1;
    cout << "Debug out : ";
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
#endif
}

template<typename T>
void debug (const T &a, string bes = "") {
#ifndef ONLINE_JUDGE
    int len = bes.length();
    cout << "Debug out : ";
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
#endif
}

void IO_Init() {
    ios::sync_with_stdio (false);
}

LL LLabs (const LL a) {
    return a >= 0 ? a : -a;
}

const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 1e3 + 5;
const int INF = 0x3f3f3f3f;

/*头文件模板*/

int main() {
#ifndef ONLINE_JUDGE
    //FIN;
    //FOUT;
#endif
    IO_Init();
    LL x, y, z, k;
    while(~scanf("%lld%lld%lld%lld", &x, &y, &z, &k)) {

        LL xx = (LL)sqrt(2LL * x) + 1;\\等加数列求和
        LL kk = (LL)sqrt(2LL * k) + 1;

        if(y == 0 && z == 0) {
            if(x == 0) xx = 0;
            else kk = 0;
        }
        if(xx * kk != y + z || xx * (xx - 1) != x * 2 || kk * (kk - 1) != k * 2) {
            puts("Impossible");
            continue;
        }

        while(xx + kk){
            if(y >= kk){
                printf("0");
                y -= kk;
                xx --;
            }
            else{
                printf("1");
                z -= xx;
                kk --;
            }
        }
        printf("\n");
    }
    return 0;
}

E. Centroids(树形DP)

time limit per test4 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output

Tree is a connected acyclic graph. Suppose you are given a tree consisting of n vertices. The vertex of this tree is called centroid if the size of each connected component that appears if this vertex is removed from the tree doesn’t exceed .

You are given a tree of size n and can perform no more than one edge replacement. Edge replacement is the operation of removing one edge from the tree (without deleting incident vertices) and inserting one new edge (without adding new vertices) in such a way that the graph remains a tree. For each vertex you have to determine if it’s possible to make it centroid by performing no more than one edge replacement.

Input

The first line of the input contains an integer n(2n400000)  — the number of vertices in the tree. Each of the next n1  lines contains a pair of vertex indices u i   and v i (1u i ,v i n)  — endpoints of the corresponding edge.

Output

Print n integers. The i  -th of them should be equal to 1  if the i  -th vertex can be made centroid by replacing no more than one edge, and should be equal to 0  otherwise.

Examples

input
3
1 2
2 3
output
1 1 1
input
5
1 2
1 3
1 4
1 5
output
1 0 0 0 0

Note

In the first sample each vertex can be made a centroid. For example, in order to turn vertex 1  to centroid one have to replace the edge (2,3)  with the edge (1,3)  .

题意

给出一棵树,要求你最多改变一条边,看这个点能否成为重心

解题思路:树形DP

基本解题思维:
对于一个不是树的重心的节点 v  ,在v 的节点数大于 n2   的子树中,找到一个最大的不超过 n2   的子树,把该子树连到 v  上,如果经过一次这样的操作,如果还存在还有子树大于n2  ,那么节点 v  就要输出0 .

此时重点即如何进行操作和判断?

设定 son[u]  为当前节点 u  的子树节点个数包括u 节点本身, pson[u]  为当前节点下的子树中节点个数满足小于等于 n2   的最大值.

接下来分两步处理:

  1. 先DFS得出每一个节点子树的节点个数和当前向下子树中节点数目小于 n2   的个数的最大值

  2. 判断当前点之前和当前之后是否满足条件

[  由于时间问题,此题题解尚未完善,其中一些原理需要用图片说明,后续补上! ] 

代码

时间复杂度:

/*头文件模板*/

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

#define pb push_back
#define mp make_pair
#define mem(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a))
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)

typedef long long LL;
typedef pair<int, int > PII;
typedef pair<int, string> PIS;
typedef pair<LL, LL>PLL;
typedef unsigned long long uLL;

template<typename T>
void print (T* p, T* q, string Gap = " ", bool flag = false) {
    int d = p < q ? 1 : -1;
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
}

template<typename T>
void print (const T &a, string bes = "") {
    int len = bes.length();
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
}

template<typename T>
void debug (T* p, T* q, string Gap = " ", bool flag = false) {
#ifndef ONLINE_JUDGE
    int d = p < q ? 1 : -1;
    cout << "Debug out : ";
    while (p != q) {
        if (flag) cout << Gap[0] << *p << Gap[1];
        else cout << *p;
        p += d;
        if (p != q && !flag) cout << Gap;
    }
    cout << endl;
#endif
}

template<typename T>
void debug (const T &a, string bes = "") {
#ifndef ONLINE_JUDGE
    int len = bes.length();
    cout << "Debug out : ";
    if (len >= 2) cout << bes[0] << a << bes[1] << endl;
    else cout << a << endl;
#endif
}

void IO_Init() {
    ios::sync_with_stdio (false);
}

LL LLabs (const LL a) {
    return a >= 0 ? a : -a;
}

const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 4e5 + 5;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;

/*头文件模板*/

int n, x, y;
int Head[MAXN], tot, son[MAXN];
int pson[MAXN], ans[MAXN];

struct o {
    int to, cost, nxt;
} E[MAXN << 1];

void init_edge() {
    mem(Head, -1);
    tot = 0;
}

void add_edge(int u, int v, int cost) {
    E[tot].to = v;
    E[tot].cost = cost;
    E[tot].nxt = Head[u];
    Head[u] = tot ++;
}

void dfs_v(int u, int f) {
    ans[u] = 1;
    son[u] = 1;
    pson[u] = 0;
    for(int v = Head[u]; ~v; v = E[v].nxt) {
        o &e = E[v];
        if(e.to == f) continue;
        dfs_v(e.to, u);
        son[u] += son[e.to];
        pson[u] = max(pson[u], pson[e.to]);
    }
    if(son[u] <= n >> 1) pson[u] = max(pson[u], son[u]);
}


void dfs_b(int u, int f, int val) {
    vector<PII> P;
    for(int v = Head[u]; ~v; v = E[v].nxt) {
        o &e = E[v];
        if(e.to == f) continue;
        P.pb(PII(pson[e.to], e.to));
    }
    sort(P.begin(), P.end(), greater<PII>() );
    for(int v = Head[u]; ~v; v = E[v].nxt) {
        o &e = E[v];
        if(e.to == f) continue;
        int nx_val = val;
        if(n - son[e.to] <= n >> 1) nx_val = max(nx_val, n - son[e.to]);
        if(e.to == P[0].second) {
            if(P.size() > 1) {
                nx_val = max(nx_val, P[1].first);
            }
        } else {
            nx_val = max(nx_val, P[0].first);
        }

        if(son[e.to] - pson[e.to] > n >> 1) {
            ans[u] = 0;
        }

        dfs_b(e.to, u, nx_val);
    }
    if(n - son[u] - val > n >> 1) {
        ans[u] = 0;
    }
}

int main() {
#ifndef ONLINE_JUDGE
    // FIN;
    // FOUT;
#endif

    IO_Init();
    while(~scanf("%d", &n)) {
        init_edge();
        for(int i = 1; i < n; i ++) {
            scanf("%d%d", &x, &y);
            add_edge(x, y, 1);
            add_edge(y, x, 1);
        }
        dfs_v(1, 0);//得到数据
        dfs_b(1, 0, 0);//判断结果
        for(int i = 1; i <= n; i ++) {
            printf("%d%c", ans[i], i == n ? '\n' : ' ');
        }
    }
    return 0;
}

[  有什么问题,记得留言哦!! ] 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值