字節跳動冬令營網絡賽 Solution

A:Alohac++

Unsolved.ide

 

B:Origamispa

Unsolved.code

題意:blog

初始的時候有一張紙,能夠從左邊往右邊摺疊,或者從右邊往左邊摺疊字符串

每次摺疊的長度不能超過現有寬度,最後摺疊到長度爲1get

從上往下看會有一個$1-n的排列$,如今給出這個排列it

問這個排列是不是合法摺疊出來的io

 

C:Continued Storyevent

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
相關文章
相關標籤/搜索