Submission #1177094

#TimeUsernameProblemLanguageResultExecution timeMemory
11770948pete8Designated Cities (JOI19_designated_cities)C++20
100 / 100
1703 ms69400 KiB
#include<bits/stdc++.h> using namespace std; #define ll long long #define f first #define s second #define pii pair<int,int> #define ppii pair<int,pii> #define vi vector<int> #define pb push_back #define all(x) x.begin(),x.end() #define rall(x) x.rbegin(),x.rend() #define F(n) for(int i=0;i<n;i++) #define lb lower_bound #define ub upper_bound #define fastio ios::sync_with_stdio(false);cin.tie(NULL); #pragma GCC optimize ("03,unroll-lopps") #define sz(x) (int)((x).size()) #define int long long using namespace std; const int mod=1e9+7,mxn=3e5,inf=1e18,minf=-1e18,lg=30,Mxn=1e6; //#undef int int n,k,m,d,q; void setIO(string name){ ios_base::sync_with_stdio(0); cin.tie(0); freopen((name+".in").c_str(),"r",stdin); freopen((name+".out").c_str(),"w",stdout); } vector<pii>adj[mxn+10]; int up[mxn+10],down[mxn+10],uc[mxn+10]; void getup(int cur,int p){ for(auto i:adj[cur]){ if(i.f==p)uc[cur]=i.s; else{ getup(i.f,cur); up[cur]+=up[i.f]+uc[i.f]; } } } void getdown(int cur,int p){ for(auto i:adj[cur])if(i.f!=p){ down[i.f]=down[cur]+up[cur]-uc[i.f]-up[i.f]+i.s; getdown(i.f,cur); } } int sz[mxn+10],del[mxn+10],tin[mxn+10],tout[mxn+10],T; struct seg{ //get mx,lazy add update pii mx[4*mxn+10]; int lazy[4*mxn+10]; void init(){for(int i=0;i<=4*T;i++)mx[i]={minf,0},lazy[i]=0;} void pull(int pos){mx[pos]=max(mx[pos<<1],mx[pos<<1|1]);} void apply(int pos,int x){ mx[pos].f+=x; lazy[pos]+=x; } void push(int pos,int l,int r){ if(l!=r){ apply(pos<<1,lazy[pos]); apply(pos<<1|1,lazy[pos]); } lazy[pos]=0; } void modify(int qpos,pii val,int pos=1,int l=0,int r=T){ if(l>qpos||r<qpos)return; if(l==r)return void(mx[pos]=val); push(pos,l,r); int mid=(l+r)>>1; modify(qpos,val,pos<<1,l,mid); modify(qpos,val,pos<<1|1,mid+1,r); pull(pos); } void update(int ql,int qr,int val,int pos=1,int l=0,int r=T){ if(l>qr||r<ql)return; if(ql<=l&&r<=qr)return void(apply(pos,val)); push(pos,l,r); int mid=(l+r)>>1; update(ql,qr,val,pos<<1,l,mid); update(ql,qr,val,pos<<1|1,mid+1,r); pull(pos); } pii qry(int ql,int qr,int pos=1,int l=0,int r=T){ if(l>qr||r<ql||l>r)return {minf,minf}; if(ql<=l&&r<=qr)return mx[pos]; push(pos,l,r); int mid=(l+r)>>1; return max(qry(ql,qr,pos<<1,l,mid),qry(ql,qr,pos<<1|1,mid+1,r)); } }t; //decomp int dist[mxn+10],ans[mxn+10],D[mxn+10]; int pa[mxn+10],node; void getsz(int cur,int p){sz[cur]=1;for(auto i:adj[cur])if(i.f!=p&&!del[i.f])getsz(i.f,cur),sz[cur]+=sz[i.f];} int getcen(int cur,int p,int need){ for(auto i:adj[cur])if(i.f!=p&&!del[i.f]){ if(sz[i.f]>need)return getcen(i.f,cur,need); } return cur; } vector<int>have; void dfs(int cur,int p,int deg){ tin[cur]=++T; have.pb(cur); D[cur]=deg; for(auto i:adj[cur])if(i.f!=p&&!del[i.f]){ dist[i.f]=dist[cur]+i.s; pa[i.f]=cur; dfs(i.f,cur,deg); } tout[cur]=T; } int dead[mxn+10]; void E(int cur){ t.modify(tin[cur],{minf,minf}); while(!dead[cur]){ t.update(tin[cur],tout[cur],dist[pa[cur]]-dist[cur]); dead[cur]=1; cur=pa[cur]; } } void solve(int cur){ getsz(cur,-1); node=getcen(cur,-1,sz[cur]/2); T=0; have.clear(); t.init(); dead[node]=1; dist[node]=0; for(int i=0;i<adj[node].size();i++)if(!del[adj[node][i].f]){ pa[adj[node][i].f]=node; dist[adj[node][i].f]=adj[node][i].s; dfs(adj[node][i].f,node,adj[node][i].f); } for(auto i:have)t.modify(tin[i],{dist[i],i}); int sum=up[node]+down[node]; if(have.size()<2)return; pii F=t.mx[1],S=max(t.qry(0,tin[D[F.s]]-1),t.qry(tout[D[F.s]]+1,T)); sum+=F.f+S.f; E(F.s); E(S.s); ans[2]=max(ans[2],sum); for(int i=0;i<have.size()-2;i++){ sum+=t.mx[1].f; E(t.mx[1].s); ans[i+3]=max(ans[i+3],sum); } for(auto i:have)dead[i]=0; del[node]=1; for(auto i:adj[node])if(!del[i.f])solve(i.f); } int32_t main(){ fastio cin>>n; int sum=0; for(int i=0;i<n-1;i++){ int a,b,c,d;cin>>a>>b>>c>>d; sum+=c; sum+=d; adj[a].pb({b,c}); adj[b].pb({a,d}); } getup(1,-1); getdown(1,-1); for(int i=1;i<=n;i++)ans[1]=max(ans[1],down[i]+up[i]); solve(1); int q;cin>>q; while(q--){ int a;cin>>a; if(a>=n)cout<<0<<'\n'; else cout<<sum-ans[a]<<'\n'; } } /* centroid decomp for each centroid we can compute answer of [1,sz[centroid]] we make every edge directed at centroid then we can choose k node and add the cost of edge (from that node to centroid) directed out of centroid *makesure not to overcount the most optimal node to choose is the leaf? we also need to pick atleast 2 diff node from diff subtree to make sure the centroid is the center */

Compilation message (stderr)

designated_cities.cpp:16:40: warning: bad option '-funroll-lopps' to pragma 'optimize' [-Wpragmas]
   16 | #pragma GCC optimize ("03,unroll-lopps")
      |                                        ^
designated_cities.cpp:23:23: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   23 | void setIO(string name){
      |                       ^
designated_cities.cpp:30:25: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   30 | void getup(int cur,int p){
      |                         ^
designated_cities.cpp:39:27: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   39 | void getdown(int cur,int p){
      |                           ^
designated_cities.cpp:51:19: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   51 |         void init(){for(int i=0;i<=4*T;i++)mx[i]={minf,0},lazy[i]=0;}
      |                   ^
designated_cities.cpp:52:26: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   52 |         void pull(int pos){mx[pos]=max(mx[pos<<1],mx[pos<<1|1]);}
      |                          ^
designated_cities.cpp:53:33: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   53 |         void apply(int pos,int x){
      |                                 ^
designated_cities.cpp:57:38: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   57 |         void push(int pos,int l,int r){
      |                                      ^
designated_cities.cpp:64:63: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   64 |         void modify(int qpos,pii val,int pos=1,int l=0,int r=T){
      |                                                               ^
designated_cities.cpp:73:68: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   73 |         void update(int ql,int qr,int val,int pos=1,int l=0,int r=T){
      |                                                                    ^
designated_cities.cpp:82:56: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   82 |         pii qry(int ql,int qr,int pos=1,int l=0,int r=T){
      |                                                        ^
designated_cities.cpp:95:25: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   95 | void getsz(int cur,int p){sz[cur]=1;for(auto i:adj[cur])if(i.f!=p&&!del[i.f])getsz(i.f,cur),sz[cur]+=sz[i.f];}
      |                         ^
designated_cities.cpp:96:34: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
   96 | int getcen(int cur,int p,int need){
      |                                  ^
designated_cities.cpp:103:31: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
  103 | void dfs(int cur,int p,int deg){
      |                               ^
designated_cities.cpp:115:15: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
  115 | void E(int cur){
      |               ^
designated_cities.cpp:123:19: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
  123 | void solve(int cur){
      |                   ^
designated_cities.cpp:153:14: warning: bad option '-funroll-lopps' to attribute 'optimize' [-Wattributes]
  153 | int32_t main(){
      |              ^
designated_cities.cpp: In function 'void setIO(std::string)':
designated_cities.cpp:25:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   25 |         freopen((name+".in").c_str(),"r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
designated_cities.cpp:26:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   26 |         freopen((name+".out").c_str(),"w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...