QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#662236#5418. Color the TreeFor_restWA 33ms13288kbC++143.9kb2024-10-20 22:06:362024-10-20 22:06:36

Judging History

你现在查看的是最新测评结果

  • [2024-10-20 22:06:36]
  • 评测
  • 测评结果:WA
  • 用时:33ms
  • 内存:13288kb
  • [2024-10-20 22:06:36]
  • 提交

answer

/*
Tips:
1.Remember to consider the zero situation in the covering problems
2.Remember to test the special small samples
3.Binary search : which side of the interval is closed
*/

#include<bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (ll i = a; i <= ll(b); ++i)
#define REP(a) for(ll i = 0;i < a;i++)
#define REM(a,b) (((a)%(b) == 0)?(b):((a)%(b)+(b))%(b)) 

typedef long long ll;
typedef double db;
constexpr ll NAX = 1e5+10;
constexpr ll M = 0;
constexpr ll PINF = 0x3FFFFFFFFFFFFFFF;
constexpr ll NINF = -0x3FFFFFFFFFFFFFFF;

ll alst[NAX],seg[NAX<<2];
vector<ll> ed[NAX];
ll n;

inline ll ls(ll a){return a<<1;}
inline ll rs(ll a){return a<<1|1;}

inline void build(ll l = 0,ll r = n-1,ll p = 1){
    if(l == r){
        seg[p] = alst[l];
        return;
    }
    ll mid = (l+r)>>1;
    build(l,mid,ls(p));
    build(mid+1,r,rs(p));
    seg[p] = min(seg[ls(p)],seg[rs(p)]);
}

ll query(ll ql,ll qr,ll p = 1,ll l = 0,ll r = n-1){
    if(l > qr || r < ql)
        return PINF;
    if(ql <= l && qr >= r)
        return seg[p];
    ll mid = (l+r)>>1;
    ll reg = PINF;
    if(!(r < ql || l > mid))
        reg = min(query(ql,qr,ls(p),l,mid),reg);
    if(!(r < mid+1 || l > qr))
        reg = min(query(ql,qr,rs(p),mid+1,r),reg);
    return reg;
}

bool vis[NAX];
ll dep[NAX],pnt[NAX][20],lg[NAX];
vector<ll> deplst[NAX];
ll maxdep = 0;

inline void dfs(ll cur){
    vis[cur] = 1;
    maxdep = max(maxdep,dep[cur]);
    deplst[dep[cur]].push_back(cur);
    FOR(i,1,19)
        pnt[cur][i] = pnt[pnt[cur][i-1]][i-1];
    for(auto tmp:ed[cur]){
        if(!vis[tmp]){
            dep[tmp] = dep[cur]+1;
            pnt[tmp][0] = cur;
            dfs(tmp);
        }
    }
}

inline ll lca(ll a,ll b){
    if(dep[a] > dep[b]) swap(a,b);
    while(dep[a] < dep[b])
        b = pnt[b][lg[dep[b]-dep[a]]];
    if(a == b) return a;
    for(ll i = 19;i >= 0;i--){
        if(pnt[a][i] != pnt[b][i])
            a = pnt[a][i],b = pnt[b][i];
    }
    return pnt[a][0];
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
    ll u,v,t;
    cin >> t;
    FOR(i,0,19)
        pnt[1][i] = 1;    
    FOR(i,2,NAX-1)
        lg[i] = lg[i/2]+1;  
    while(t--){
        cin >> n;
        deplst[0].clear();
        FOR(i,1,n){
            ed[i].clear();
            vis[i] = 0;
            deplst[i].clear();
            maxdep = 0;
        }
        FOR(i,0,n-1)
            cin >> alst[i];
        build();
        FOR(i,1,n-1){
            cin >> u >> v;
            ed[u].push_back(v);
            ed[v].push_back(u);
        }
        dep[1] = 0;
        dfs(1);
        ll ans = alst[0];
        FOR(k,1,maxdep){
            vector<ll> dp(deplst[k].size());
            stack<array<ll,2>> st;
            st.push({-1,-1});
            dp[0] = query(0,k);
            FOR(i,0,(int)deplst[k].size()-2){
                ll p = lca(deplst[k][i],deplst[k][i+1]);
                if(dep[p] > st.top()[0])
                    st.push({dep[p],i});
                while(dep[p] < st.top()[0]){
                    ll last = st.top()[1];
                    dp[i] = min(((last > 0?dp[last-1]:0))+query(k-st.top()[0],k),dp[i]);
                    // cout << p << ' ' << last << ' ' << ((last > 0?dp[last-1]:0))+query(k-st.top()[0],k) << endl;
                    st.pop();
                }
                if(st.size() == 1) st.push({dep[p],0});
                dp[i+1] = dp[i]+query(0,k);
            }
            while(st.size() != 1){
                ll last = st.top()[1];
                dp.back() = min(((last > 0?dp[last-1]:0))+query(k-st.top()[0],k),dp.back());
                // cout << k-st.top()[0] << ' ' << k << ' ' << query(k-st.top()[0],k) << '\n';
                st.pop();
            }
            // cout << dp.back() << ' ';
            ans += dp.back();
        }
        cout << ans << '\n';
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 12016kb

input:

3
4
10 15 40 1
1 2
2 3
2 4
5
10 5 1 100 1000
1 2
2 3
2 4
4 5
4
1000 200 10 8
1 2
2 3
3 4

output:

35
17
1218

result:

ok 3 number(s): "35 17 1218"

Test #2:

score: -100
Wrong Answer
time: 33ms
memory: 13288kb

input:

3000
54
43 44 11 49 17 14 7 30 35 12 34 14 15 8 29 47 30 31 39 17 26 23 26 45 34 50 49 13 35 18 29 15 13 44 47 5 22 20 19 46 30 22 26 13 47 46 43 27 48 48 13 14 30 44
1 2
1 3
2 4
3 5
4 6
2 7
4 8
1 9
3 10
1 11
8 12
2 13
9 14
1 15
1 16
15 17
15 18
7 19
1 20
19 21
13 22
10 23
17 24
9 25
9 26
24 27
8 28...

output:

180
174
222
230
156
240
225
126
100
81
171
73
154
139
149
133
228
230
140
191
153
170
78
282
195
286
200
211
119
197
211
252
88
252
239
244
173
180
195
121
109
148
180
182
226
210
182
97
211
59
56
31
115
214
203
172
139
208
53
143
189
174
173
137
233
94
163
273
80
350
156
133
153
159
240
269
137
222...

result:

wrong answer 2nd numbers differ - expected: '168', found: '174'