字节跳动冬令营网络赛 Solution

A:Aloha

Unsolved.

 

B:Origami

Unsolved.

题意:

初始的时候有一张纸,可以从左边往右边折叠,或者从右边往左边折叠

每次折叠的长度不能超过现有宽度,最后折叠到长度为1

从上往下看会有一个$1-n的排列$,现在给出这个排列

问这个排列是否是合法折叠出来的

 

C:Continued Story

Unsolved.

题意:

有一个有根树,根为1,两个人轮流操作,每一次操作时选择一条边将其边权减一

如果某一次操作后对应的边的边权变为0,那么这条边会被移除

此时树会被分成两块,没有根的那块会被移除(根为1)

 

D:The Easiest One

Unsolved.

题意:

定义两种操作:

$x = x - 1$

$x = x - 2^i (当x AND 2^i != 0 时可以用)$

定义$f(x, y) 为 x 变成y 所需的最少操作数 此处(y <= x)$

求$\sum_{0 <= y <= x <= n} f(x, y)$

 

E:Set

Unsolved.

题意:

有n个集合,每个集合的大小都为m, 并且要满足$|S_i - S_{(i - 1 + n) mod n} | >= l_i$

现在要使得所有集合的并的元素个数最小,求最小的数量

 

F:Old Problem

Unsolved.

在$n x m 的矩形里 有 (n - 1) (m - 1) 个点,有有多少个三点能够组成直角三角形$

 

 

G:Periodic Palindrome

Unsolved.

 

H:Accel World

Unsolved.

 

I:Hello, Hello and Hello

Unsolved.

题意:

有一个字符串,当开始是 $000....111...222 这样的$

每一次可以选择其中一个子串把它放到后面,求最小的操作次数使得任意相邻的字符都不相同

无法做到输出-1

 

J:Sortable Path on Tree

Upsolved.

题意:

有一棵树,求存在多少个$pair(u, v) 使得u ->v 的简单路径上所有点按顺序组成的点权序列$

使得存在一个起点,使得从这个起点开始往后是一个非递减序列,(可以看作一个环此时)

思路:

点分治

我们将一个序列用大于号和小于号串起来

$这样对于某种符号数>=2的,直接视为2$

$那么只有9种状态来表示一个点$

$在对每棵子树分治的时候我们只需要考虑如何拼接形态即可$

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define N 100010
  6 int t, n;
  7 int w[N];
  8 vector <int> G[N];
  9 ll res;
 10 
 11 struct BIT
 12 {
 13     int a[N];
 14     void init() { memset(a, 0, sizeof a); }
 15     void update(int x, int val)
 16     {
 17         for (; x <= 100000; x += x & -x)
 18             a[x] += val;
 19     }
 20     int query(int x)
 21     {
 22         int res = 0;
 23         for (; x > 0; x -= x & -x)
 24             res += a[x];
 25         return res;
 26     }
 27     int query(int l, int r) { if (r < l) return 0; return query(r) - query(l - 1); }
 28 }bit[3][3]; 
 29 
 30 int vis[N];
 31 int root, sum, sze[N], f[N];
 32 void getroot(int u, int fa)
 33 {
 34     sze[u] = 1, f[u] = 0;
 35     for (auto v : G[u]) if (v != fa && !vis[v])
 36     {
 37         getroot(v, u);
 38         sze[u] += sze[v];
 39         f[u] = max(f[u], sze[v]);
 40     }
 41     f[u] = max(f[u], sum - sze[u]);
 42     if (f[u] < f[root]) root = u;
 43 }
 44 
 45 int big[N], small[N];
 46 void getdeep(int u, int fa)
 47 {
 48     if (big[u] > 2) big[u] = 2;
 49     if (small[u] > 2) small[u] = 2;
 50     int x = big[u], y = small[u];
 51     for (int i = 0; i <= 2; ++i)
 52         for (int j = 0; j <= 2; ++j)
 53         {
 54             int nx = x + i;
 55             int ny = y + j;
 56             if (nx >= 2 && ny >= 2) continue;
 57             if (!nx || !ny || (nx == 1 && ny == 1)) res += bit[i][j].query(100000);
 58             else if (nx == 1) res += bit[i][j].query(1, w[u]);
 59             else if (ny == 1) res += bit[i][j].query(w[u], 100000);
 60         }
 61     for (auto v : G[u]) if (v != fa && !vis[v])
 62     {
 63         big[v] = big[u] + (w[v] > w[u]);
 64         small[v] = small[u] + (w[v] < w[u]);
 65         getdeep(v, u); 
 66     }
 67 }
 68 
 69 void add(int u, int fa, int flag)
 70 {
 71     bit[small[u]][big[u]].update(w[u], flag);
 72     for (auto v : G[u]) if (v != fa && !vis[v]) 
 73         add(v, u, flag);  
 74 }
 75 
 76 void solve(int u)
 77 {
 78     vis[u] = 1; 
 79     bit[0][0].update(w[u], 1);
 80     for (auto v : G[u]) if (!vis[v])
 81     {
 82         big[v] = (w[v] > w[u]);
 83         small[v] = (w[v] < w[u]);  
 84         getdeep(v, u);
 85         add(v, u, 1);
 86     }
 87     for (auto v : G[u]) if (!vis[v]) add(v, u, -1);
 88     bit[0][0].update(w[u], -1); 
 89     for (auto v : G[u]) if (!vis[v])
 90     {
 91         sum = f[0] = sze[v]; root = 0;
 92         getroot(v, 0);
 93         solve(root);
 94     }
 95 }
 96 
 97 int main()
 98 {
 99     scanf("%d", &t);
100     while (t--)
101     {
102         scanf("%d", &n); 
103         for (int i = 1; i <= n; ++i) G[i].clear(), vis[i] = 0;
104         for (int i = 1; i <= n; ++i) scanf("%d", w + i);
105         for (int i = 1, u, v; i < n; ++i)
106         {
107             scanf("%d%d", &u, &v);
108             G[u].push_back(v);
109             G[v].push_back(u);
110         }
111         res = 0; 
112         sum = f[0] = n; root = 0;
113         getroot(1, 0);
114         solve(root);
115         printf("%lld\n", res + n);
116     }
117     return 0;
118 }
View Code

 

posted @ 2018-12-01 18:58  Dup4  阅读(414)  评论(0编辑  收藏  举报