結果
問題 | No.901 K-ary εxtrεεmε |
ユーザー | hirayuu_yc |
提出日時 | 2024-04-29 17:15:10 |
言語 | C++23(gcc13) (gcc 13.2.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 409 ms / 3,000 ms |
コード長 | 14,945 bytes |
コンパイル時間 | 4,239 ms |
コンパイル使用メモリ | 304,236 KB |
実行使用メモリ | 48,220 KB |
最終ジャッジ日時 | 2024-11-18 22:54:00 |
合計ジャッジ時間 | 14,704 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 179 ms
48,220 KB |
testcase_01 | AC | 2 ms
6,820 KB |
testcase_02 | AC | 4 ms
6,820 KB |
testcase_03 | AC | 4 ms
6,816 KB |
testcase_04 | AC | 4 ms
6,820 KB |
testcase_05 | AC | 4 ms
6,816 KB |
testcase_06 | AC | 4 ms
6,816 KB |
testcase_07 | AC | 373 ms
47,108 KB |
testcase_08 | AC | 352 ms
47,352 KB |
testcase_09 | AC | 351 ms
47,152 KB |
testcase_10 | AC | 366 ms
47,012 KB |
testcase_11 | AC | 366 ms
47,212 KB |
testcase_12 | AC | 367 ms
47,288 KB |
testcase_13 | AC | 350 ms
47,232 KB |
testcase_14 | AC | 367 ms
47,124 KB |
testcase_15 | AC | 347 ms
47,368 KB |
testcase_16 | AC | 339 ms
47,192 KB |
testcase_17 | AC | 378 ms
47,080 KB |
testcase_18 | AC | 385 ms
47,132 KB |
testcase_19 | AC | 352 ms
47,356 KB |
testcase_20 | AC | 351 ms
47,228 KB |
testcase_21 | AC | 359 ms
47,292 KB |
testcase_22 | AC | 406 ms
47,232 KB |
testcase_23 | AC | 399 ms
47,292 KB |
testcase_24 | AC | 409 ms
47,192 KB |
testcase_25 | AC | 386 ms
47,112 KB |
testcase_26 | AC | 403 ms
47,356 KB |
testcase_27 | AC | 382 ms
47,228 KB |
testcase_28 | AC | 383 ms
47,000 KB |
testcase_29 | AC | 406 ms
47,236 KB |
コンパイルメッセージ
/root/AtCoder/Halc-Library/Tree/StaticTopTree.hpp: In member function 'int32_t StaticTopTree<M>::_merge(std::vector<int>&, std::vector<int>&, int32_t, int32_t, bool) [with M = solve()::steiner]': /root/AtCoder/Halc-Library/Tree/StaticTopTree.hpp:112:5: warning: control reaches end of non-void function [-Wreturn-type]
ソースコード
#line 1 "main.cpp" #define PROBLEM "https://yukicoder.me/problems/no/901" #line 2 "/root/AtCoder/Halc-Library/Template/Template.hpp" //https://tatyam.hatenablog.com/entry/2019/12/15/003634 #include<bits/stdc++.h> using namespace std; using ll=long long; template<class T> using pq=priority_queue<T,vector<T>,greater<T>>; using pll=pair<ll,ll>; const ll LINF=1LL<<60; #define _overload3(_1,_2,_3,name,...) name #define _overload4(_1,_2,_3,_4,name,...) name #define _rep1(i,n) for(ll i=0; i<(n); i++) #define _rep2(i,a,b) for(ll i=(a); i<(b); i++) #define _rep3(i,a,b,c) for(ll i=(a); i<(b); i+=(c)) #define rep(...) _overload4(__VA_ARGS__,_rep3,_rep2,_rep1)(__VA_ARGS__) #define _rrep1(i,n) for(ll i=(n); i-->0;) #define _rrep2(i,a,b) for(ll i=(b); i-->(a);) #define rrep(...) _overload3(__VA_ARGS__,_rrep2,_rrep1)(__VA_ARGS__) #define each(i,...) for(auto&& i:__VA_ARGS__) #define all(i) begin(i),end(i) #define rall(i) rbegin(i),rend(i) template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return true;}else return false;} template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return true;}else return false;} template<class T> ll sum(const T &a){return accumulate(all(a),0LL);} template<class T> auto min(const T &a){return *min_element(all(a));} template<class T> auto max(const T &a){return *max_element(all(a));} inline int scan(){ return getchar(); } inline void scan(int &a){ scanf("%d", &a); } inline void scan(unsigned &a){ scanf("%u", &a); } inline void scan(long &a){ scanf("%ld", &a); } inline void scan(long long &a){ scanf("%lld", &a); } inline void scan(unsigned long long &a){ scanf("%llu", &a); } inline void scan(char &a){ cin >> a; } inline void scan(float &a){ scanf("%f", &a); } inline void scan(double &a){ scanf("%lf", &a); } inline void scan(long double &a){ scanf("%Lf", &a); } inline void scan(vector<bool> &vec){ for(unsigned i = 0; i < vec.size(); i++) { int a; scan(a); vec[i] = a; } } inline void scan(char a[]){ scanf("%s", a); } inline void scan(string &a){ cin >> a; } template<class T> inline void scan(vector<T> &vec); template<class T, size_t size> inline void scan(array<T, size> &vec); template<class T, class L> inline void scan(pair<T, L> &p); template<class T, size_t size> inline void scan(T (&vec)[size]); template<class T> inline void scan(vector<T> &vec){ for(auto &i : vec) scan(i); } template<class T> inline void scan(deque<T> &vec){ for(auto &i : vec) scan(i); } template<class T, size_t size> inline void scan(array<T, size> &vec){ for(auto &i : vec) scan(i); } template<class T, class L> inline void scan(pair<T, L> &p){ scan(p.first); scan(p.second); } template<class T, size_t size> inline void scan(T (&vec)[size]){ for(auto &i : vec) scan(i); } template<class T> inline void scan(T &a){ cin >> a; } inline void in(){} template <class Head, class... Tail> inline void in(Head &head, Tail&... tail){ scan(head); in(tail...); } inline void print(){ putchar(' '); } inline void print(const bool &a){ printf("%d", a); } inline void print(const int &a){ printf("%d", a); } inline void print(const unsigned &a){ printf("%u", a); } inline void print(const long &a){ printf("%ld", a); } inline void print(const long long &a){ printf("%lld", a); } inline void print(const unsigned long long &a){ printf("%llu", a); } inline void print(const char &a){ printf("%c", a); } inline void print(const char a[]){ printf("%s", a); } inline void print(const float &a){ printf("%.15f", a); } inline void print(const double &a){ printf("%.15f", a); } inline void print(const long double &a){ printf("%.15Lf", a); } inline void print(const string &a){ for(auto&& i : a) print(i); } template<class T> inline void print(const vector<T> &vec); template<class T, size_t size> inline void print(const array<T, size> &vec); template<class T, class L> inline void print(const pair<T, L> &p); template<class T, size_t size> inline void print(const T (&vec)[size]); template<class T> inline void print(const vector<T> &vec){ if(vec.empty()) return; print(vec[0]); for(auto i = vec.begin(); ++i != vec.end(); ){ putchar(' '); print(*i); } } template<class T> inline void print(const deque<T> &vec){ if(vec.empty()) return; print(vec[0]); for(auto i = vec.begin(); ++i != vec.end(); ){ putchar(' '); print(*i); } } template<class T, size_t size> inline void print(const array<T, size> &vec){ print(vec[0]); for(auto i = vec.begin(); ++i != vec.end(); ){ putchar(' '); print(*i); } } template<class T, class L> inline void print(const pair<T, L> &p){ print(p.first); putchar(' '); print(p.second); } template<class T, size_t size> inline void print(const T (&vec)[size]){ print(vec[0]); for(auto i = vec; ++i != end(vec); ){ putchar(' '); print(*i); } } template<class T> inline void print(const T &a){ cout << a; } inline int out(){ putchar('\n'); return 0; } template<class T> inline int out(const T &t){ print(t); putchar('\n'); return 0; } template<class Head, class... Tail> inline int out(const Head &head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; } using ld=long double; using ull=unsigned long long; using uint=unsigned int; using pii=pair<int,int>; using pdd=pair<ld,ld>; using tuplis=array<ll,3>; #define vec(type,name,...) vector<type> name(__VA_ARGS__); #define vv(type,name,h,...)vector<vector<type>> name(h,vector<type>(__VA_ARGS__)); #define INT(...) int __VA_ARGS__; in(__VA_ARGS__) #define LL(...) ll __VA_ARGS__; in(__VA_ARGS__) #define ULL(...) ull __VA_ARGS__; in(__VA_ARGS__) #define STR(...) string __VA_ARGS__; in(__VA_ARGS__) #define CHR(...) char __VA_ARGS__; in(__VA_ARGS__) #define LD(...) ld __VA_ARGS__; in(__VA_ARGS__) #define VEC(type,name,size) vector<type> name(size); in(name) #define VV(type, name, h, w) vector<vector<type>> name(h, vector<type>(w)); in(name) template<class T> ld dsum(const T &a){return accumulate(all(a),0.0L);} const int INF=INT_MAX>>1; const ll MINF=1LL<<40; const ld DINF=numeric_limits<ld>::infinity(); const int MODD=1000000007; const int MOD=998244353; const ld EPS=1e-9; const ld PI=3.1415926535897932; const ll four[]={0,1,0,-1,0}; const ll eight[]={0,1,1,0,-1,-1,1,-1,0}; ll intpow(ll a,ll b){ll ret=1;while(b){if(b&1)ret*=a;a*=a;b>>=1;}return ret;} int Yes(bool i=true){return out(i?"Yes":"No");} int No(bool i=true){return out(i?"No":"Yes");} #define len(x) ((int)(x).size()) #define fi first #define se second #line 2 "/root/AtCoder/Halc-Library/Tree/StaticTopTree.hpp" template<class M> struct StaticTopTree{ using point=typename M::point; using path=typename M::path; struct Node{ bool is_path; point point_val; path path_val; int32_t pos; int32_t left; int32_t right; int32_t parent; Node(bool pat,int32_t po=-1,int32_t lf=-1,int32_t ri=-1){ is_path=pat; pos=po; left=lf; right=ri; parent=-1; } }; size_t sz; vector<vector<int32_t>> tree; vector<int32_t> node_pos; vector<Node> nodes; int32_t rt; StaticTopTree(size_t size){ sz=size; tree.resize(sz); node_pos.resize(sz); } void add_edge(int32_t s,int32_t v){ tree[s].emplace_back(v); tree[v].emplace_back(s); } int32_t _path_cluster(int32_t pos,vector<int32_t> &tree_sz){ if(tree[pos].empty()){ node_pos[pos]=nodes.size(); nodes.emplace_back(Node(1,pos)); _calc_val(nodes.size()-1); return nodes.size()-1; } vector<int32_t> address; vector<int32_t> sizes; while(!tree[pos].empty()){ int32_t max_size=-1; int32_t next_pos=-1; for(int i=0; i<tree[pos].size(); i++){ if(tree_sz[tree[pos][i]]>max_size){ max_size=tree_sz[tree[pos][i]]; next_pos=i; } } swap(tree[pos][next_pos],tree[pos].back()); next_pos=tree[pos].back(); tree[pos].pop_back(); tree_sz[pos]-=tree_sz[next_pos]; sizes.emplace_back(tree_sz[pos]); address.emplace_back(_point_cluster(pos,tree_sz)); pos=next_pos; } address.emplace_back(_point_cluster(pos,tree_sz)); sizes.emplace_back(tree_sz[pos]); return _merge(address,sizes,0,address.size(),1); } int32_t _point_cluster(int32_t pos,vector<int32_t> &tree_sz){ if(tree[pos].empty()){ node_pos[pos]=nodes.size(); nodes.emplace_back(Node(1,pos)); _calc_val(nodes.size()-1); return nodes.size()-1; } vector<int32_t> address; vector<int32_t> sizes; for(int32_t i:tree[pos]){ sizes.emplace_back(tree_sz[i]); int32_t vert=_path_cluster(i,tree_sz); nodes.emplace_back(Node(0,-1,vert)); nodes[vert].parent=nodes.size()-1; address.emplace_back(nodes.size()-1); _calc_val(nodes.size()-1); } int32_t vert=_merge(address,sizes,0,address.size(),0); node_pos[pos]=nodes.size(); nodes.emplace_back(Node(1,pos,vert)); nodes[vert].parent=nodes.size()-1; _calc_val(nodes.size()-1); return nodes.size()-1; } int32_t _merge(vector<int32_t> &address,vector<int32_t> &sizes,int32_t lf,int32_t ri,bool pat){ if(lf+1==ri)return address[lf]; int32_t add=0; for(int32_t i=lf; i<ri; i++){ add+=sizes[i]; } int32_t now=0; int32_t bef=add+1; for(int32_t i=lf; i<ri; i++){ now+=sizes[i]; if(now>add-now){ if(now+now-add>bef)i--; int32_t left=_merge(address,sizes,lf,i+1,pat); int32_t right=_merge(address,sizes,i+1,ri,pat); nodes.emplace_back(Node(pat,-1,left,right)); nodes[left].parent=nodes.size()-1; nodes[right].parent=nodes.size()-1; _calc_val(nodes.size()-1); return nodes.size()-1; } bef=add-now-now; } } void _calc_val(int32_t pos){ if(nodes[pos].is_path){ if((nodes[pos].left==-1) && (nodes[pos].right==-1)){ nodes[pos].path_val=M::vertex(nodes[pos].pos); } else if((nodes[pos].left!=-1) && (nodes[pos].right!=-1)){ nodes[pos].path_val=M::compress(nodes[nodes[pos].left].path_val,nodes[nodes[pos].right].path_val); } else{ nodes[pos].path_val=M::add_vertex(nodes[nodes[pos].left].point_val,nodes[pos].pos); } } else{ if((nodes[pos].left!=-1) && (nodes[pos].right!=-1)){ nodes[pos].point_val=M::rake(nodes[nodes[pos].left].point_val,nodes[nodes[pos].right].point_val); } else{ nodes[pos].point_val=M::add_edge(nodes[nodes[pos].left].path_val); } } } void build(int32_t root){ vector<int32_t> vert(sz); vector<int32_t> tree_sz(sz,-1); vert[0]=root; tree_sz[0]=0; int32_t cnt=1; for(int32_t i=0; i<sz; i++){ for(int32_t j:tree[vert[i]]){ if(tree_sz[j]){ tree_sz[j]=0; vert[cnt]=j; cnt++; } } } for(int32_t i=sz-1; i>=0; i--){ int32_t parent=0; for(int32_t j:tree[vert[i]]){ if(tree_sz[j]==0){ parent=-parent-1; } if(parent>=0)parent++; tree_sz[vert[i]]+=tree_sz[j]; } if(parent<0){ swap(tree[vert[i]][-parent-1],tree[vert[i]].back()); tree[vert[i]].pop_back(); } tree_sz[vert[i]]++; } rt=_path_cluster(root,tree_sz); } path root_value(){ return nodes[rt].path_val; } void calc(int32_t pos){ int32_t change=node_pos[pos]; while(nodes[change].parent!=-1){ _calc_val(change); change=nodes[change].parent; } _calc_val(change); } size_t size(){ return sz; } }; #line 4 "main.cpp" void solve(){ LL(N); static vector<bool> mark(N,0); static vector<ll> weight(N,-1); struct steiner{ using point=array<ll,5>; using path=array<ll,6>; static path vertex(int v){ if(mark[v]){ return {1,0,0,0,0,weight[v]}; } return {0,0,0,0,0,weight[v]}; } static path compress(path p,path c){ if(p[0]==0 && c[0]==0){ return {0,0,0,p[3]+c[3]+c[5],p[3]+c[3]+c[5],p[5]}; } if(p[0]==1 && c[0]==0){ return {1,p[1],p[2],p[3],p[4]+c[3]+c[5],p[5]}; } if(p[0]==0 && c[0]==1){ return {1,c[1],c[2],p[3]+c[3]+c[5],c[4],p[5]}; } return {1,p[2]+c[2]+p[4]+c[3]+c[5],p[2]+c[2]+p[4]+c[3]+c[5],p[3],c[4],p[5]}; } static path add_vertex(point t,int v){ if(t[0]==0){ if(mark[v]){ return {1,0,0,0,0,weight[v]}; } return {0,0,0,0,0,weight[v]}; } if(t[3]==0){ if(mark[v]){ return {1,t[2]+t[4],t[2]+t[4],0,0,weight[v]}; } return {1,t[1],t[2]+t[4],0,0,weight[v]}; } return {1,t[2]+t[4],t[2]+t[4],0,0,weight[v]}; } static point rake(point x,point y){ if(x[0]<y[0])swap(x,y); if(x[0]==0 && y[0]==0){ return {0,0,0,0,0}; } if(x[0]==1 && y[0]==0){ return x; } return {1,x[2]+y[2],x[2]+y[2],1,x[4]+y[4]}; } static point add_edge(path t){ if(t[0]==0){ return {0,0,0,0,0}; } return {1,t[1],t[2]+t[3],0,t[5]}; } }; StaticTopTree<steiner> tree(N); vv(pll,gr,N); rep(i,N-1){ LL(u,v,w); tree.add_edge(u,v); gr[u].push_back(pll(v,w)); gr[v].push_back(pll(u,w)); } weight[0]=0; stack<ll> vert; vert.push(0); while(!vert.empty()){ ll pos=vert.top(); vert.pop(); for(auto &[t,w]:gr[pos]){ if(weight[t]==-1){ weight[t]=w; vert.push(t); } } } tree.build(0); LL(Q); rep(i,Q){ LL(k); VEC(ll,x,k); each(j,x){ mark[j]=1; tree.calc(j); } out(tree.root_value()[1]); each(j,x){ mark[j]=0; tree.calc(j); } } } int main(){ solve(); return 0; }