Brief description:
Problem A. Dynasty Puzzles
略。(.G[a][b] 表示以 a 开始 b 结尾的最长串的长度。。最后统计所有 G[a][a] ….
Problem B. Demonstration
读题压力巨大,那个啥。。大概的意思是有一个一行 n 的位置,每个位置有一个价值 ai …
然后对立的两个势力进行如下的博弈 .
..
A 势力(以下简称进攻方)的目的是得到一个尽可能靠左的位置,
每回合它可以选择任意一个位置占据。
B 势力(以下简称防御方)的目的是使得进攻方的结果尽可能糟糕,
。。每当进攻方选择了一个位置之后,防御方可以有以下两个决策。
1. 花费 ai 块钱。。让 A 势力滚回老家结婚。(该位置永远无法再次选择,并且 A 势力自动获得最靠右的那个格子)
2. 预算不足。。占据就占据吧。。
问一个 k 回合,防御方资金为 B 的游戏,进攻方所能得到的最好成绩。。
然后题目里一大段不自然的文字大概是说。。
1. 防御方的策略是贪心的。。(只要有钱就封杀直到没钱。。
2. 排除一些 bug 情况。。比如如果游戏途中某个位置进攻方占领了,它还可以向更左边的位置进军。。
。。。
(于是这个题读懂以后基本算法就已经给你了。。(为毛我感觉大家做法和我都不一样 0w0 。。。
。。按 ai 对位置进行排序。。(注意最后一个位置的价值是没有意义的。。用 0 替代。。
。。之后二分判定。。(。。从大到小。。遇到我们要的格子时暂跳过。。留到最后一回合。。。
。之后再从左到右扫描一遍找到第一个 ≥ 这个值的位置即可。。。)
Problem C. Fools and Roads:
给定一颗 n 个结点的树,以及 m 对访问信息。
问每条边被经过了多少次。。
Problem D. Metro Scheme:
给定一个地铁图。。。(。地铁分两类。。A 类线形。。B 类环形。。)
。。满足图是一个仙人掌图。。(。一个点最多只可能在一个环上。。)
。问形成这个图最多和最少需要几条地铁线呢。。
Problem E. Thwarting Demonstrations:
给定一个长度为 n 的数组,问在所有区间和之中 (。。共 C(n, 2) 组)。。
第 k 大的是多少。
(.. n <= 10^5 .. .)
Analysis:
Problem C. Fools and Roads:
。。动态树。(。类似去年多校的 这题。。
。轻重链树链剖分。。或者 LCA() + DFS() 都可行。。)
Problem D. Metro Scheme:
。。貌似最多的就是边数。。于是最小的怎么求 。。0w0?。。
我就去看了一眼 bjin 的代码。。发现只要先统计下欧拉路径的数目。。再在原图上找环就行了。。。
前者统计下奇数度定点数目 / 2 。。。后者可以直接在图上缩环。。0w0。。复杂度 O(n)。。。
Problem E. Thwarting Demonstrations:
二份答案判定,则子问题为,大于等于 x 的区间和的数量超过 k 吗?
这个经典的子问题解决办法有很多,这里用实现最容易的树状数组。
大概是这个样子。。
bool f(LL x, LL k) {
RST(C); REP(i, n){
Add(lower_bound(a, a + n, s[i]) - a + 1, 1);
k -= Sum(lower_bound(a, a + n, s[i+1] - x + 1) - a);
if (k <= 0) return true;
}
return false;
}
。。。。
int G[26][26], n;
int main(){
while (scanf("%d", &n) != EOF && n){
string s; REP(i, n){
cin >> s; int a = s[0] - 'a', b = s[SZ(s)-1] - 'a';
REP(i, 26) if (G[i][a]) checkMax(G[i][b], G[i][a] + SZ(s));
checkMax(G[a][b], SZ(s));
}
int ans = 0; REP(i, 26){
checkMax(ans, G[i][i]);
}
cout << ans << endl;
}
}
const int N = 100009;
int A[N], O[N]; LL B;
int n, k;
bool comp(int a, int b){
return A[a] > A[b] || A[a] == A[b] && a < b;
}
bool f(int x){
x = O[x];
int i = 0, t = k - 1; LL b = B;
while (t){
if (O[i] == x) ++i;
b -= A[O[i]];
++i, --t;
}
return b < A[x];
}
int main(){
RD(n, k); cin >> B; REP(i, n) RD(A[i]), O[i] = i; A[n-1] = 0;
sort(O, O + n, comp);
if (!f(0)){
cout << n << endl;
return 0;
}
int l = 0, r = n - 2;
while (l < r){
int m = (l + r + 1) / 2;
if (f(m)) l = m;
else r = m - 1;
}
REP(i, n) if (A[i] >= A[O[l]]){
cout << i + 1 << endl;
return 0;
}
}
const int N = 100009, M = 2 * N;
int l[N], r[N], p[N], w0[N], w1[N], delay[N]; bool rt[N];
// Link-cut tree
int hd[N], nxt[M], a[M], b[M];
// Adjacent list
int n, ans;
#define lx l[x]
#define rx r[x]
// private:
inline void Inc(int x, int d){
if (x == 0) return;
w0[x] += d, w1[x] += d, delay[x] += d;
}
inline void Release(int x){
if (x == 0) return;
if (delay[x]){
Inc(lx, delay[x]), Inc(rx, delay[x]);
delay[x] = 0;
}
}
inline void Update(int x){
w1[x] = w0[x] + w1[lx] + w1[rx];
}
inline void Set(int l[], int y, int x){
l[y] = x, p[x] = y;
}
#define z p[y]
inline void Rotate(int x){
int y = p[x];
if (!rt[y]) Release(z), Set(y == l[z] ? l : r, z, x);
else p[x] = z;
Release(y), Release(x);
if (x == l[y]) Set(l, y, rx), Set(r, x, y);
else Set(r, y, lx), Set(l, x, y);
if (rt[y]) rt[y] = false, rt[x] = true;
Update(y);
}
inline void Splay(int x){
while (!rt[x]) Rotate(x);
}
inline int Access(int x){
int y = 0; do{
Splay(x), Release(x);
rt[rx] = true, rt[rx = y] = false, Update(x);
x = p[y = x];
} while (x);
return y;
}
// public:
void Query(int x, int y){
Access(y), y = 0; do{
Splay(x); Release(x); if (!p[x]) OT(w1[rx] + w1[y]);
rt[rx] = true, rt[rx = y] = false; Update(x);
x = p[y = x];
} while (x);
}
void Modify(int x, int y, int w){
Access(y); y = 0; do{
Splay(x), Release(x); if (!p[x]) Inc(rx, w), Inc(y, w);
rt[rx] = true, rt[rx = y] = false, Update(x);
x = p[y = x];
} while (x);
}
#define v b[i]
inline void dfs(int u = 1){
for(int i=hd[u];i;i=nxt[i]) if (!p[v]){
p[v] = u, dfs(v);
}
}
int main(){
#ifdef LOCAL
//freopen("in01.txt", "r", stdin);
#endif
FOR_C(i, 2, _RD(n) << 1){
RD(a[i], b[i]), a[i|1] = b[i], b[i|1] = a[i];
nxt[i] = hd[a[i]], hd[a[i]] = i; ++i;
nxt[i] = hd[a[i]], hd[a[i]] = i;
}
FLC(rt, true), p[1] = -1, dfs(), p[1] = 0;
int x, y; DO_C(RD()){
RD(x, y); Modify(x, y, 1);
}
FOR(i, 1, n) Query(a[i<<1], b[i<<1]);
}
const int N = 100009;
VI adj[N];
int n, m, ans;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int a, b; RD(n, m); REP(i, m){
RD(a, b), --a, --b, adj[a].PB(b), adj[b].PB(a);
}
#define deg(x) SZ(adj[x])
REP(i, n) if (deg(i)&1) ++ans;
ans >>= 1;
REP(i, n) if (deg(i) == 2){
a = adj[i][0], b = adj[i][1];
if (a == b){
CLR(adj[a]);
++ans;
}
else {
adj[a][adj[a][0] == i ? 0 : 1] = b;
adj[b][adj[b][0] == i ? 0 : 1] = a;
}
}
printf("%d %d\n", ans, m);
}
const int N = 100009;
int C[N]; LL s[N], a[N];
int n; LL k;
void Add(int x, int d){
for (int i=x;i<=n;i+=low_bit(i)) C[i] += d;
}
LL Sum(int x){
LL res = 0; for(int i=x;i;i^=low_bit(i)) res += C[i];
return res;
}
bool f(LL x, LL k) {
RST(C); REP(i, n){
Add(lower_bound(a, a + n, s[i]) - a + 1, 1);
k -= Sum(lower_bound(a, a + n, s[i+1] - x) - a);
if (k <= 0) return true;
}
return false;
}
//((s[r] - s[l-1]) >= x)
//s[l-1] <= s[r] - x ...
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
scanf("%d %I64d", &n, &k);
//scanf("%d %lld", &n, &k);
REP(i, n) s[i+1] = s[i] + RD();
REP(i, n) a[i] = s[i]; sort(a, a + n);
LL l = -1e14 - 1, r = 1e14 - 1;
while (l <= r) {
LL m = (l + r) / 2;
if (f(m, k)) l = m + 1;
else r = m - 1;
}
printf("%I64d\n", l);
//printf("%lld\n", l - 1);
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos

请问有没有讲解动态树或树链剖分的论文?
好像有。。)
前排仰慕岛妹!~