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 }