- Published on
@JR OIer attended on "Spectral: :Cup 2026 Round 2 (Codeforce Round 1100, Div. 1 + Div. 2) Editual"
- Authors

- Name
- aimode.news
- @aimode_news
Thank you for participating in our round!
Prepared by:
Editoral by: reirigan
Let
Let
We want to choose the value of
#Include
typedef long long longll;
#definine debug(x) cout < #x < "= "< x < "\n";
#define vdebug(a) cout < < #a < < " = " ; for (auto x: a) cout < < < < " ; cout < < " \ " ;
mt19937 rang (chrono:steady clock:now() .time since epoch() .count());
Intuid(int a, int b)
ll uld(ll a, ll b)
void Solve(){
I don't know.
I'm sorry.
vector
For (int & x: a) cin > x;
Int mx = *max election (a.begin(), a.end());
Int mn = *min election (a.begin(), a.end());
Cout < (mx - mn + 1) / 2 < "n";
♪ I'm sorry ♪
Intmain(){
OS:: sync with stdio (false);
cin.tie (0);
Int t;
cin> > t;
(b) While (t-);
♪ I'm sorry ♪
Idea by: Intellegent
Prepared by:
Editoral by: reirigan
For one of the indices, you will gain equal to
It is never bad to put the larger value in
We should swim any
#Include
typedef long long longll;
#definine debug(x) cout < #x < "= "< x < "\n";
#define vdebug(a) cout < < #a < < " = " ; for (auto x: a) cout < < < < " ; cout < < " \ " ;
mt19937 rang (chrono:steady clock:now() .time since epoch() .count());
Intuid(int a, int b)
ll uld(ll a, ll b)
void Solve(){
I don't know.
I'm sorry.
vector
For (int & x: a) cin > x;
For (int & x: b) cin > x;
ll sum = 0;
for (int i = 0; i < n; i ++)
sum + = max (a [i], b[i];
♪ Ans = 0;
for (int i = 0; i < n; i ++)
Ans = max (ans, sum + min (a[i], b[i]));
What's going on?
♪ I'm sorry ♪
Intmain(){
OS:: sync with stdio (false);
cin.tie (0);
Int t;
cin> > t;
(b) While (t-);
♪ I'm sorry ♪
2229C1 - We Be Flipping (Easy Version) 2229C2 - We Be Flipping (Hard Version)
Idea by: Intellegent
Prepared by:
Editoral by: reirigan
You can make this elegance without placing any later elegations by applying an operation to it directly.
Let
Read the points. In fact, it is always possible to make all elections before
To make all of the elections before
#Include
typedef long long longll;
#definine debug(x) cout < #x < "= "< x < "\n";
#define vdebug(a) cout < < #a < < " = " ; for (auto x: a) cout < < < < " ; cout < < " \ " ;
mt19937 rang (chrono:steady clock:now() .time since epoch() .count());
Intuid(int a, int b)
ll uld(ll a, ll b)
void Solve(){
I don't know.
I'm sorry.
vector
For (int & x: a) cin > x;
Int par = 0;
vector
For (int i = n - 1; i > = 0; i-){
If (par = 1)
a[i] = -a[i];
If (a[i] > 0){
Ans.push back(i);
Par ^ 1;
♪ I'm sorry ♪
♪ I'm sorry ♪
Cout < ns. size() < "n";
for (int i = 0; i < ans. size(; i ++)
cout < < ans[i] + 1 < "\n" [i = ans.size() - 1];
♪ I'm sorry ♪
Intmain(){
OS:: sync with stdio (false);
cin.tie (0);
Int t;
cin> > t;
(b) While (t-);
♪ I'm sorry ♪
#Include
typedef long long longll;
#definine debug(x) cout < #x < "= "< x < "\n";
#define vdebug(a) cout < < #a < < " = " ; for (auto x: a) cout < < < < " ; cout < < " \ " ;
mt19937 rang (chrono:steady clock:now() .time since epoch() .count());
Intuid(int a, int b)
ll uld(ll a, ll b)
void Solve(){
I don't know.
I'm sorry.
vector
For (int & x: a) cin > x;
vector
[0] = abs (a [0];
for (int i = 1; i < n; i ++)
Pre[i] = pre[i-1] + abs (a[i];
suf[n - 1] = a [n - 1];
For (int i = n - 2; i > = 0; i--)
suf[i] = suf[i + 1] + a[i];
ll best = suf [0];
Int idx = -1;
for (int i = 1; i < n; i++){
If (a[i] > 0){
ll score = pre[i - 1] + suf [i + 1] - a[i];
If (score > best){
Best = score;
idx = i;
♪ I'm sorry ♪
♪ I'm sorry ♪
♪ I'm sorry ♪
If (idx = -1)
I'm sorry.
I don't know.
♪ I'm sorry ♪
vector
For (int i = idx-1; i > = 0; i--){
If (ans.size() & 1)
a[i] = -a[i];
If (a[i] > 0)
Ans.push back(i);
♪ I'm sorry ♪
Ans.push back(idx);
Cout < ns. size() < "n";
for (int i = 0; i < ans. size(; i ++)
cout < < ans[i] + 1 < "\n" [i = ans.size() - 1];
♪ I'm sorry ♪
Intmain(){
OS:: sync with stdio (false);
cin.tie (0);
Int t;
cin> > t;
(b) While (t-);
♪ I'm sorry ♪
Idea by: Intellegent
Prepared by:
Editoral by: reirigan
Try solving the problem on a binary basis; that is, all values of
Supper you want to check if it is possible to achieve a final value of at least
This allows you to believe in the final answer.
- Yes, sir.
Now, it is impossible to address
#Include
typedef long long longll;
#definine debug(x) cout < #x < "= "< x < "\n";
#define vdebug(a) cout < < #a < < " = " ; for (auto x: a) cout < < < < " ; cout < < " \ " ;
mt19937 rang (chrono:steady clock:now() .time since epoch() .count());
Intuid(int a, int b)
ll uld(ll a, ll b)
void Solve(){
I don't know.
I'm sorry.
vector
For (int & x: a) cin > x;
For (int & x: b) cin > x;
Int l = 0, r = 1e9 + 5;
While (l< r){
Int Mid = (l + r) / 2;
Int one = 0, zero = 0;
Not prev = -1;
for (int i = 0; i < n; i+){
Int type = 0;
If (a[i] > = mid)
type++;
If (b[i] > = mid)
type++;
If (type = 1)
I'm sorry.
If (type = 2)
One++;
Prev = 1;
♪ I'm sorry ♪
If (type = 0){
If (prev! = 0)
zero++;
Prev = 0;
♪ I'm sorry ♪
♪ I'm sorry ♪
If (one > zero)
l = mid + 1;
I'm sorry, else.
r = mid;
♪ I'm sorry ♪
I'm sorry, I'm sorry.
♪ I'm sorry ♪
Intmain(){
OS:: sync with stdio (false);
cin.tie (0);
Int t;
cin> > t;
(b) While (t-);
♪ I'm sorry ♪
Idea by: Intellegent
Prepared by:
Educational by:
Try rooting at
Read the points, through this editoral I will consider
Lets try to define the following for each node.
& max For this to happen there must be some leave outside the subtree than each element of the subtree. If
We can solve this problem with dynamic programming where
It should be note that transfers to
#Include
typedef long long longll;
#definine debug(x) cout < #x < "= "< x < "\n";
#define vdebug(a) cout < < #a < < " = " ; for (auto x: a) cout < < < < " ; cout < < " \ " ;
mt19937 rang (chrono:steady clock:now() .time since epoch() .count());
Intuid(int a, int b)
ll uld(ll a, ll b)
= 998244353;
timedate
Other Organiser
Static constexpr bool is big mod =mod > numeric limites
Using S = general t
Using L = general t
S x;
Modenum(): x(0){
modnum(ll x){
x %= status cast
x+=mod;}
x = x;
♪ I'm sorry ♪
modnum pow (ll n) const {
Modnum rees = 1;
Modnum Cur = *this;
While (n > 0) {
If (n & 1) res* = cur;
Cur*=cur;
n = 2;
♪ I'm sorry ♪
I'm sorry.
♪ I'm sorry ♪
modnum inv() const {return(*this). pow(mod-2;}
{(contmodnum&a){
x + = a.x;
If (x > = mod) x - = mod;
What's going on?
♪ I'm sorry ♪
{(contmodnum&a){
If (x < a.x) x + = mod;
x - = a.x;
What's going on?
♪ I'm sorry ♪
== sync, corrected by elderman ==
x = status cast
What's going on?
♪ I'm sorry ♪
=(contmodnum & a)
{return Modenum(a)+=b;}
{return Modnum(a) - =b;}
*
}
== sync, corrected by elderman == @elder man
== sync, corrected by elderman ==
{cont MODnum & b) {return a. x < b.x;}
{os < a.x; return os;}
{ll x; is > x; a = modnum (x); return is;}
};
We're going to have to go to the hospital.
void Solve(){
I don't know.
I'm sorry.
vector
for (int i = 0; i < n - 1; i ++){
Int u, v;
cin > u > v;
u-;
v-;
g [u].push back(v);
g[v].push back(u);
♪ I'm sorry ♪
If (g[n-1]. size()=1){
What's going on?
I don't know.
♪ I'm sorry ♪
vector
Autu dfs = [ ] (auto self, int c, int p) - >void{
For (int x: g[c]{
If (x = p)
I'm sorry.
Self (self, x, c);
mx[c] = max({mx[c], x, mx[x]});
♪ I'm sorry ♪
};
dfs (dfs, n - 1, 1);
Set
for (int i = 0; i < n - 1; i ++)
s.insert(i);
vector
Auto dfs2 = [ /] (auto self, int c, int p) - >void{
s.erace(c);
cur.push back(c);
For (int x: g[c]{
If (x = p)
I'm sorry.
Self (self, x, c);
♪ I'm sorry ♪
};
vector
For (int x: g[n-1]){
dfs2 (dfs2, x, n - 1);
For (int u: cur){
If (u > (*s.begin()))
Ok[u] = true;
♪ I'm sorry ♪
For (int u: cur)
s.insert (u);
Cur.clar();
♪ I'm sorry ♪
[n-1] = true;
Int idx = -1;
for (int i = 0; i < n; i+){
If (g[i]. size() = 1)
idx = i;
♪ I'm sorry ♪
vector
dp [idx] = 1;
= 1;
for (int i = idx + 1; i < n - 1; i ++){
Int l = mx[i] + 1;
If (l< i){
dp[i] = pre[i-1];
If (l > 0)
dp[i] - = pre[l-1];
♪ I'm sorry ♪
pre[i] = dp[i] + pre[i-1];
♪ I'm sorry ♪
mint ans = 0;
for (int i = 0; i < n; i+){
If (ok[i])
ns + = dp[i];
♪ I'm sorry ♪
What's going on?
♪ I'm sorry ♪
Intmain(){
OS:: sync with stdio (false);
cin.tie (0);
Int t;
cin> > t;
(b) While (t-);
♪ I'm sorry ♪
Idea by: myst-6
Prepared by:
Editoral by: sammyuri
Which element of
Now what does the problem return to you?
To maximise the minute value of
We can make the bitmask dp in the form dp [mask] = number of groups, leftover. There are
We can use this greeny algorithm to protect that
#Include
typedef long long longll;
#define all(x) x.begin(), x.end()
#define vecin
#define vecoout(v) for (auto : v) cout < < < " ; cout < endl;
void Solve() {
Not n, k; cin > n > k;
(aa, n); sort (all (aaa));
No, no, no, no.
ll extra = aa.back(); aa.pop back();
ll L = 0, R = extra * (ll)n;
& While
ll Mid = (L + R + 1) / 2;
vector
for (int i = 1; i < (1< n; i ++){
for (int j = 0; (1< j) < = i; j ++) {
If! (i & (1< j)) continue;
Int res = i ^ (1 < j);
Pair
Cur.second+=aa[j];
If (cur.second > = mid)
Other Organiser
dp[i] = max (dp[i], cur);
♪ I'm sorry ♪
♪ I'm sorry ♪
If (dp[ (1 < n) - 1]. first > = k)
L = mid;
I'm sorry, else.
R = mid-1;
♪ I'm sorry ♪
Not < L + extra < < endl;
♪ I'm sorry ♪
inmain(){
OS base:: sync with stdio (false);
cin.tie (NULL);
Inttt = 1;
cin > tt;
(b) while (tt...) Solve();
Return 0;
♪ I'm sorry ♪
Idea by:
Prepared by:
Editoral by: sammyuri
When is it to stay at a house for more than
Supper you are staying at a house for more than
Supper you are staying at a house for more than
First, until that any house you stay at for longer than
Also, if you are going to stay at a house for longer than
Finely, if you are going to switch directs in an alternative solution, you should go all the way past house
We know that for each house, the average answer on that house at time
For the sake of case, we can maintain which house is the prefix maxim on both sides, and for the better case case, we can use force to keep track of the best conservation if we respond on house
Supper you are staying at a house for more than
In fact, we can show that whenever you reach a prefix maxim, the next house you will move to is either the next High Prefix maxim on that side of
#Include
typedef long long longll;
#define all(x) x.begin(), x.end()
#define vecin
#define vecoout(v) for (auto : v) cout < < < " ; cout < endl;
Standard Line
I don't know.
{(cont Line& o)Const {return k < o.k;}
{ll x) const {return p < x;}
ll eval(ll x)
};
Standard LineContainer: multiset
= LLONG MAX;
ll div(ll a,ll b)
return a / b -((a ^ b) < 0 & a %b; }
Bool test
If (y = end()) return x->p = inf, 0;
If (x->k = = y->k) x-mp = x-m > y-m? inf:-inf;
=div (y->m-x-m, x->k-y->k);
Return x->p = y->p;
♪ I'm sorry ♪
void add(ll k,ll m)
auto z = insert(k, m, ), y = z++, x = y;
While (isect(y,z)) z = erace(z);
If (x! = begin() & & subject(-, y) isect(x, y = example(y));
While ((y = x)! = begin() & (-x)->p > = y->p)
isect(x, example(y));
♪ I'm sorry ♪
ll query(ll x){
Asert(!impty());
Auto l = *lower born (x);
Return l.eval(x);
♪ I'm sorry ♪
};
vector
vector
llrange sum(int L, int R){
Return pref[R + 1] - pref[L];
♪ I'm sorry ♪
void Solve() {
Int n, t, x; cin > n > t > x;
x-;
h.resize(n); pref.resize(n+1);
Pref[0] = 0;
for (int i = 0; i < n; i ++){
cin > h[i];
pref[i + 1] = pref[i] + h[i];
♪ I'm sorry ♪
vecin(d, n-1);
for (int i = x - 2; i > = 0; i --) {
d [i] = max(d[i], d[i + 1] + 1);
♪ I'm sorry ♪
for (int i = x; i < n - 2; i ++) {
d [i + 1] = max (d [i + 1], d [i] + 1);
♪ I'm sorry ♪
ll ans = h[x]*t;
Int L = x, R = x;
Line Curleft = h[x], 0,
Int left best=x, right best=x;
LineContainer left, right?
left.add(h[x], 0); right.add(h[x], 0);
Que.
While (L > 0 ||R< n-1) {
Int left time=(L=0)? 2e9 : d [L-1];
Int right time = (R = n - 1) 2e9: d[R];
> t) break;
If (left time< = right time)
L-;
If (h[L] > Curleft.k) {
/ best = max sum on day left time-1 on house L+1
= left best-L;
Instart dist=x-L;
While (add right. size() & add right. front(). first < = left time - start dist) {
Right.add(add right.front().second.first, add right.front().second.second.second);
Add right.pop();
♪ I'm sorry ♪
ll best = max
+ renge sum (L + 1, left best-1),
Right. querry (left time -start dist)+range sum (L+1, x-1)
(b) ;
/ Cout < L < " < h [L] < " < best < endl;
Ans = max(ans, best + (t - left time + 1) *h [L];
left best=L;
Curleft = {h[L], best - (left time - 1) *h [L],
dd left.push({left time + start dist, {h[L], best - (left time-1 + start dist) *h[L] + range sum(L+1, x)});
♪ I'm sorry ♪
♪ Orse ♪
R ++;
If (h[R] > control.k) {
/ best = max sum on day right time-1 on house R-1
= R-right best;
Instart dist=R-x;
While (add left. size() & add left. front(). first < = right time-start dist) {
Left.add (add left.front().second.first, add left.front().second.second);
Add lift.pop();
♪ I'm sorry ♪
ll best = max
Right time - pref dist)+range sum (right best+1, R-1),
Left. Query (right time - start dist)+range sum (x + 1, R-1)
(b) ;
/ cout < R < " < h [R] < " < best < endl;
Ans = max(ans, best + (t - right time + 1) *h [R];
Right best=R;
== sync, corrected by elderman == @elder man
Add right.push({right time + start dist, {h[R], best - (right time-1 + start dist) *h [R] + range sum(x, R-1}});
♪ I'm sorry ♪
♪ I'm sorry ♪
♪ I'm sorry ♪
What's up?
♪ I'm sorry ♪
inmain(){
OS base:: sync with stdio (false);
cin.tie (NULL);
Inttt = 1;
cin > tt;
(b) while (tt...) Solve();
Return 0;
♪ I'm sorry ♪
#Include
We'll = long long long;
= vector
= vector
We're using pl = pair
timedate
timedate
template
Oh, yeah.
#definine FOR2(i, a) for (int i = 0; i < int(a); +i)
#definine FOR3 (i, a, b) for (int i = int(a); i < int(b); +i)
#definine FOR2 R(i, a) for (int i = int(a)-1; i > = 0; --i)
#definine overload4 (a, b, c, d, e, e)
#definine overload3 (a, b, c, d, ...) d
#definine FOR(...) overload4( VA ARGS , 4, FOR3, FOR2, 1) ( VA ARGS )
#definine FOR R(...) overload3( VA ARGS , 3, FOR2 R, 1) ( VA ARGS )
#define all(x).begin(),(x).end()
#definine track(a, x) for (auto& a: x)
#Define eb place back
# Define mp make
# Definine fi first
#Define us second #
timedate
T c = max
Bool changed = (c! = a);
a = c;
I'm sorry.
♪ I'm sorry ♪
timedate
timedate
void read()}
timedate
void pent(){cout< 'n';}
timedate Tail
void print (head & head, tail &...tail) {
I don't know.
If (sizeof... (Tail)) cut < ' ;
print(forward)
♪ I'm sorry ♪
#definine INT(...) int VA ARGS; read
#definine LL(...)ll VA ARGS; read( VA ARGS )
#definine VEC (type, name, size)
void Solve() {
INT(N); LL(t); INT(X);
X-;
VEC (ll, A, N);
VEC (ll, D, N-1);
vl T(N);
T[X] = 1;
FOR(i, X, N-1){
T[i+1] = max (T[i]+1, D[i];
If (i = = X & D [i] = 1) T [i + 1] = 1;
♪ I'm sorry ♪
FOR R(i, X){
T[i] = max (T[i+1]+1, D[i];
(i) = X-1 & D[i] = 1) T[i] = 1;
♪ I'm sorry ♪
vi (N), lh (N);
vc
stk.eb (mp(N, 2e9);
FOR R(i), {
While (stk.back().se < = A[i]) stk.pop back();
n[i] = stk.back().fi;
stk.eb (mp(i, A[i)]);
♪ I'm sorry ♪
stk.clar();
stk.eb (mp(-1, 2e9);
& FOR(i), {
While (stk.back().se < = A[i]) stk.pop back();
lh[i] = stk.back().fi;
stk.eb (mp(i, A[i)]);
♪ I'm sorry ♪
ll dp [N];
& FOR(i), {
dp[i]=-infoty
♪ I'm sorry ♪
For(i), N) dp[i] = 0;
vc
sort (vals);
♪ Ans = 0;
vl ps; ps.eb (0);
FOR(i), N) ps.eb(ps.back()+A[i]);
Trav(xx, vals){
Int i = xx.se;
If (dp [i] < 0) continue;
Chmax(ans, (tot-T[i]+1) *A[i] + dp[i];
vi ops = n[i], lh[i]};
Trav(j, ops){
If (j < 0 j > = N) continue;
If (abs(j-i) > T[j] - T[i] {
I'm sorry.
♪ I'm sorry ♪
Chmax(dp[j], dp[i]+ (T[j] - T[i] - abs(j-i) + 1) *A[i] + ps[max(i, j)] - ps[min(i, j) + 1];
♪ I'm sorry ♪
♪ I'm sorry ♪
(e) print(s);
♪ I'm sorry ♪
Signed Main()
OS:: sync with stdio (false);
cin.tie (nulrptr);
INT (T);
FOR(t), {t]
Solve();
♪ I'm sorry ♪
Return 0;
♪ I'm sorry ♪
Idea by: Intellegent
Prepared by:
Educational by:
Imagine the string has no
Try to generalise this greeny for when there are
Read the points.
We would like to find a situation of
Say we have a match where at some point we didn't choose the early match, say between
Now lets try to promote this when there are
It fails because we properly assume the value of a
To fix this problem, we can assume our greeny to consider both parents at the same time.
The prof for this greeny is simple to the naïve greeny in the no
Now for accounting, we can run dynamic programming on this greeny. Where?
This is the final time.
#Include
typedef long long longll;
#definine debug(x) cout < #x < "= "< x < "\n";
#define vdebug(a) cout < < #a < < " = " ; for (auto x: a) cout < < < < " ; cout < < " \ " ;
mt19937 rang (chrono:steady clock:now() .time since epoch() .count());
Intuid(int a, int b)
ll uld(ll a, ll b)
= 998244353;
timedate
Other Organiser
Static constexpr bool is big mod =mod > numeric limites
Using S = general t
Using L = general t
S x;
Modenum(): x(0){
modnum(ll x){
x %= status cast
x+=mod;}
x = x;
♪ I'm sorry ♪
modnum pow (ll n) const {
Modnum rees = 1;
Modnum Cur = *this;
While (n > 0) {
If (n & 1) res* = cur;
Cur*=cur;
n = 2;
♪ I'm sorry ♪
I'm sorry.
♪ I'm sorry ♪
modnum inv() const {return(*this). pow(mod-2;}
{(contmodnum&a){
x + = a.x;
If (x > = mod) x - = mod;
What's going on?
♪ I'm sorry ♪
{(contmodnum&a){
If (x < a.x) x + = mod;
x - = a.x;
What's going on?
♪ I'm sorry ♪
== sync, corrected by elderman ==
x = status cast
What's going on?
♪ I'm sorry ♪
=(contmodnum & a)
{return Modenum(a)+=b;}
{return Modnum(a) - =b;}
*
}
== sync, corrected by elderman == @elder man
== sync, corrected by elderman ==
{cont MODnum & b) {return a. x < b.x;}
{os < a.x; return os;}
{ll x; is > x; a = modnum (x); return is;}
};
We're going to have to go to the hospital.
void Solve(){
I don't know.
I'm sorry.
I don't know.
cin > s;
s = '0' + s;
n+;
vector
= s[0] = = '1';
for (int i = 1; i < n; i++){
Pre[i] = pre[i-1] + (s[i] = = '1');
♪ I'm sorry ♪
vector
For (int i = 0; i < = n; i ++){
To [i][0][0] = n;
To [i] [0][1] = n;
To [i] [1][0] = n;
To [i] [1][1] = n;
Int cnt = 0;
Bool wowee = false;
For (int j = i + 1; j < n; j +){
If(cnt & 1) &!wowe){
If (s[j] = = '1')
cnt++;
If (s[j] = = '?')
= true;
I'm sorry.
♪ I'm sorry ♪
If (s[j] = = '1')
cnt++;
If (s[j] = = '?')
= true;
Int par = pre[j] & 1;
If (s[j] = = '?')
To [i] [0] [par] = min (to [i] [0] [par], j);
To [i] [1] [par] = min (to [i] [1] [par], j);
I'm sorry.
♪ I'm sorry ♪
Int og = s[j] - '0';
To [i] [omg] [par] = min (to [i] [omg] [par], j);
♪ I'm sorry ♪
♪ I'm sorry ♪
vector
Int cnt = 0;
Int wowee = false;
For (int i = n - 1; i > = 0; i-){
good[i] = (cnt %2 = 0) || wowee;
If (s[i]=='1')
cnt++;
If (s[i] = = '?')
= true;
♪ I'm sorry ♪
mint ans = 0;
vector
dp [0][n] = 1;
vector
For (int i = 0; i < = n; i ++){
for (int j = i; j < = n; j ++){
Ord.push back(i,j});
If (j! = i)
Ord.push back({j, i});
♪ I'm sorry ♪
♪ I'm sorry ♪
For (auto [i, j]: ord){
For (int nxt = 0; nxt < 2; nxt++){
Int even =min (to [i][nxt][0], to [j][nxt][0];
Int odd = min (to [i] [nxt [1], to [j] [nxt [1]);
dp[even][odd]+=dp[i][j];
♪ I'm sorry ♪
If (good[i] || good[j])
ns + = dp[i] [j];
♪ I'm sorry ♪
What's going on?
♪ I'm sorry ♪
Intmain(){
OS:: sync with stdio (false);
cin.tie (0);
Int t;
cin> > t;
(b) While (t-);
♪ I'm sorry ♪
Idea by:
Prepared by:
Editoral by: sammyuri
It's not convex, montone, FFT, controid, or any other fancy trick like that. Reformulate the future for scure so that it's in terms of nodes in the subtree from root, not the path to the root.
How many DPs do you compute for the node exclusively care about?
[i] be the maximme score of a subset of nodes of nodeline of nodei, assuring the self-made root isi or an objector of i, who uses literally nodes.
Let's get together.
Supplose we are at a node
Observe that we only need to compute
All that remains is to add the condition of node
Then, for a nonde
We can make it one!
The only thing to watch out for is that communication of the original node
#Include
typedef long long longll;
#define all(x) x.begin(), x.end()
#define vecin
#define vecoout(v) for (auto : v) cout < < < " ; cout < endl;
Const int MAXN = 4005;
ll dp down [MAXN] [MAXN], dp down take [MAXN] [MAXN], dp up [MAXN] [MAXN];
ll pref merge [MAXN] [MAXN], suff merge [MAXN] [MAXN];
vector
vector
♪ Light [MAXN];
Int sz [MAXN];
Inn n, k;
void dfs1 (int node, in parent)
sz [node] = 1;
For (auto a: adj [node])
If (a! = parent)
Children [node].push back(a);
dfs1 (a, node);
For (int i = min (sz [node] - 1, k); i > = 0; i-)
for (int j = 1; j < = sz [a] & i + j < = k; j +)
dp down [node] [i + j] = max (dp down [node] [i + j], dp down [node] [i] + dp down take[a] [j];
sz [node]+=sz[a];
♪ I'm sorry ♪
For (int i = min(k, sz [node]; i > 0; i-)
dp down take [node][i] = max (dp down [node][i], dp down [node][i-1] + (ll)i * weight [node];
♪ I'm sorry ♪
void dfs2 (int node){
Int deg = children [node]. size();
If (deg = 1) {
for (int i = 0; i < = k; i ++)
dp up [children [node][0] [i]=dp up[node][i];
{else if (deg > = 2) {
Int p = sz [children [node][0];
for (int i = 0; i < = k; i ++)
= dp down take [children [node][0]][i],
suff merge[deg][i]=dp up[node][i];
for (int c = 1; c < dig; c ++){
for (int i = 0; i < = k; i ++)
= 0;
Int child = children [node] [c];
p + = sz [child];
for (int i = min (k, p); i > = 0; i-)
For (int j = min (i, sz [child]; j > = 0 & & i - j < = p - sz [child]; j --)
pref merge[c][i] = max (pref merge[c][i], pref merge[c-1][i-j]+dp down take[child][j]]);
♪ I'm sorry ♪
For (int c = dig-1; c > = 0; c-) {
for (int i = 0; i < = k; i ++)
suff merge[c][i] = 0;
Int child = children [node] [c];
p - = sz [child];
for (int i = k; i > = max (0, k - p - 1); i-)
For (int j = min (i, sz [child]; j > = 0; j --)
suff merge[c][i] = max (suff merge[c][i], suff merge[c + 1] [i-j] + dp down take[child] [j]]);
for (int i = k; i > = max (0, k - sz [child] - 1); i-)
For (int j = min (i, p); j > = 0; j-)
dp up[child][i] = max(dp up[child][i], suff merge[c + 1] [i-j]+(c > 0]? pref merge[c-1][j]:0);
♪ I'm sorry ♪
♪ I'm sorry ♪
For (auto a: children [node])
for (int i = min(k, n - sz[a]; i > = 1; i-)
dp up[a] [i] = max (dp up [a] [i], dp up[a] [i-1] + (ll)i * weight [node]]);
dfs2(a);
♪ I'm sorry ♪
♪ I'm sorry ♪
void Solve() {
cin > n > k;
for (int i = 0; i < n; i ++){
for (int j = 0; j < = k; j ++)
dp down[i] [j]=dp down take[i] [j]=dp up[i] [j]=0;
Adj [i].clar(); children[i].clar();
cin> weight[i];
♪ I'm sorry ♪
For (int i = 0; i < n - 1; i ++){
Int a, b; cin > a > b;
a; b -;
Adj [a].push back(b);
Adj [b]. Push back(a);
♪ I'm sorry ♪
dfs1 (0, 1);
dfs2(0);
for (int i = 0; i < n; i ++){
ll best = 0;
for (int j = 0; j < min(k, sz[i]; j ++)
Best = max (best, dp down[i] [j] + dp up[i] [k - 1 - j] + (ll)k * weight[i];
Cout < best < " ;
♪ I'm sorry ♪
I don't know.
♪ I'm sorry ♪
inmain(){
OS base:: sync with stdio (false);
cin.tie (NULL);
Inttt = 1;
cin > tt;
(b) while (tt...) Solve();
Return 0;
♪ I'm sorry ♪
#Include
typedef long long longll;
#define all(x) x.begin(), x.end()
#define vecin
#define vecoout(v) for (auto : v) cout < < < " ; cout < endl;
Const int MAXN = 4005;
Inn n, k;
I don't know.
vector
ll beauty [2* MAXN];
Int sz [2* MAXN];
ll dp down [2* MAXN] [MAXN], dp down take [2* MAXN] [MAXN];
ll dp up [2* MAXN] [MAXN];
{lll *target, *ll *bb, int tsize, int *bsize, int *
for (int i = tsize; i > max (0, tsize -topmost); i --)
for (int j = 0; j < = min (asize, bsize), i); j ++
= max (target[i], asize > =bsize? aa[i-j] + bb[j]: bb[i-j] + aa[j];
♪ I'm sorry ♪
void finalise (ll *target, ll time, ll b, int tsize)
for (int i = tsize; i > 0; i-)
+ (ll)i*b);
♪ I'm sorry ♪
void dfs1 (int node, in parent)
vector
For (auto a: adj [node])
If (a! = parent)
dfs1 (a, node);
cc.push back(a);
♪ I'm sorry ♪
Incur = node;
While (cc. size() > 2) {
Children [cur] = {cc.back(), spare};
cc.pop back();
Beauty [spare] = beauty [node];
Cur = spare ++;
♪ I'm sorry ♪
Children [cur] = cc;
♪ I'm sorry ♪
void dfs2 (int node){
sz [node] = (node < n);
For (auto a: children [node])
dfs2(a);
sz [node]+=sz[a];
♪ I'm sorry ♪
If (children [node]. size()=1) {
for (int i = 0; i < = k; i ++)
dp down [node][i] = dp down take[node][0] [i];
{Other if (children [node]. size()=2)}
Merge (dp down [node], dp down take [children [node] [0], dp down take [children [node] [1]), Min (k, sz [node] - (node < n)), sz [children [node] [node], sz [children [node][1], sz [node] - (node < n)]);
♪ I'm sorry ♪
Finalise (dp down take[node], dp down [node], node < n ? beauty [node]: 0, min(k, sz [node]]);
♪ I'm sorry ♪
void dfs3 (int node){
If (children [node]. size()=1) {
(dp up [children [node][0]], dp up [node], pretty [node], min (k, n - sz [children [node][0]]));
{Other if (children [node]. size()=2)}
Int aa = children [node][0], b b = children [node][1];
(dp up [aa], dp up [node], dp down take [bb], Min (n - sz [aa], k), Min (n - sz [node], k), Min (sz [bb], k), Min (sz [aa] + 2, k));
(dp up [bb], dp up [node], dp down take [aa], Min (n - sz [bb], k), Min (n - sz [node], k), Min (sz [aa], k), Min (sz [bb] + 2, k));
If (aa < n)
Finalise (dp up [aa], dp up [aa], pretty [node], min (n - sz [aa], k));
If (bb < n)
Finalise (dp up [bb], dp up [bb], pretty [node], min (n - sz [bb], k));
♪ I'm sorry ♪
For (auto a: children [node])
dfs3 (a);
♪ I'm sorry ♪
void Solve() {
cin > n > k;
for (int i = 0; i < n; i ++)
Adj [i].clar(), children[i].clar();
For (int i = n; i < 2 * n; i ++)
Children[i].clar();
spare = n;
for (int i = 0; i < n; i ++)
cin > beauty[i];
For (int i = 0; i < n - 1; i ++){
Int a, b; cin > a > b;
a; b -;
Adj [a].push back(b);
Adj [b]. Push back(a);
♪ I'm sorry ♪
dfs1 (0, 1);
for (int i = 0; i < spare; i ++)
for (int j = 0; j < = k; j ++)
dp down[i] [j]=dp up[i] [j]=dp down take[i] [j]=0;
dfs2(0);
dfs3 (0);
for (int i = 0; i < n; i ++){
ll best = 0;
for (int j = 0; j < min(k, sz[i]; j ++)
best = max (best, dp down[i][j] + dp up[i][k - 1 - j] + (ll)k * pretty[i];
Cout < best < " ;
♪ I'm sorry ♪
I don't know.
♪ I'm sorry ♪
inmain(){
OS base:: sync with stdio (false);
cin.tie (NULL);
Inttt = 1;
cin > tt;
(b) while (tt...) Solve();
Return 0;
♪ I'm sorry ♪