Submission #1202294

#TimeUsernameProblemLanguageResultExecution timeMemory
12022948pete8JOI tour (JOI24_joitour)C++20
16 / 100
347 ms214732 KiB
#include "joitour.h" #include<bits/stdc++.h> using namespace std; #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 lb lower_bound #define ub upper_bound #define fastio ios::sync_with_stdio(false);cin.tie(NULL); #pragma GCC optimize("O3") #pragma GCC target("avx2,popcnt,lzcnt,abm,bmi,bmi2,fma,tune=native,sse,sse2,sse3") #define int long long using namespace std; const int mod=1e9+7,mxn=2e5+5,inf=1e18,minf=-1e18,lg=31,Mxn=6e6,base=131; //#undef int int n,k,m,q,L,T; 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); } int F[mxn+10]; vector<int>adj[mxn+10]; enum Type{Vertex,Compress,Rake,AddEdge,AddVertex}; struct sttree{ int root,stroot; vector<int>P,L,R; vector<Type>T; int ct; void init(int x){ root=x; build(); } private: int gethvy(int cur,int p){ int best=0,sz=1; for(auto &i:adj[cur])if(i!=p){ int x=gethvy(i,cur); sz+=x; if(x>best)best=x,swap(adj[cur][0],i); } //if(adj[cur].size())cout<<cur<<" "<<adj[cur][0]<<"?\n"; return sz; } int add(int k,int l,int r,Type t){ if(k==-1)k=++ct; L[k]=l,R[k]=r,T[k]=t; if(l!=-1)P[l]=k; if(r!=-1)P[r]=k; return k; } pii merge(vector<pii>have,Type t){ if(have.size()==1)return have[0]; int cs=0; for(auto i:have)cs+=i.s; vector<pii>a,b; for(auto i:have){ if(i.s<cs)a.pb(i); else b.pb(i); cs-=2*i.s; } pii x=merge(a,t),y=merge(b,t); return {add(-1,x.f,y.f,t),x.s+y.s}; } pii compress(int cur){ vector<pii>have={addvertex(cur)}; while(adj[cur].size())cur=adj[cur][0],have.pb(addvertex(cur)); return merge(have,Type::Compress); } pii rake(int cur){ vector<pii>have; for(int i=1;i<adj[cur].size();i++)have.pb(addedge(adj[cur][i])); return have.empty()? (pii){-1,0} : merge(have,Type::Rake); } pii addedge(int cur){ pii x=compress(cur); return {add(-1,x.f,-1,Type::AddEdge),x.s}; } pii addvertex(int cur){ pii x=rake(cur); return {add(cur,x.f,-1,(x.f==-1)?Type::Vertex : Type::AddVertex),x.s+1}; } void build(){ P.resize(4*n+1,-1),L.resize(4*n+1,-1),R.resize(4*n+1,-1); T.resize(4*n+1); ct=n; gethvy(root,-1); stroot=compress(root).f; } }; struct path{ int dp[3][3],ca=0; int c=0;//cnt 1 path(){ for(int i=0;i<3;i++)for(int j=0;j<3;j++)dp[i][j]=0; } }; struct point{ int dp[3][3],ca=0,ca2=0; point(){for(int i=0;i<3;i++)for(int j=0;j<3;j++)dp[i][j]=0;} }; path vertex(int i){ path x; x.dp[F[i]][F[i]]++; if(F[i]==1)x.c++; return x; } path compress(path a,path b){ path x; x.ca+=(a.dp[0][0]*b.dp[1][2])+(a.dp[1][0]*b.dp[2][2])+(a.dp[2][2]*b.dp[1][0])+(a.dp[1][2]*b.dp[0][0]); x.ca+=a.ca+b.ca; x.dp[1][0]+=a.c*b.dp[0][0]; x.dp[1][2]+=a.c*b.dp[2][2]; x.c=a.c+b.c; for(int i=0;i<3;i++)for(int j=0;j<3;j++)x.dp[i][j]+=a.dp[i][j]+b.dp[i][j]; //cout<<x.ca<<" "<<a.dp[0][0]<<" "<<b.dp[2][2]<<" "<<a.c<<" "<<b.c<<"??\n"; return x; } point rake(point a,point b){ point x; x.ca+=(a.dp[0][0]*b.dp[1][2])+(a.dp[1][0]*b.dp[2][2])+(a.dp[2][2]*b.dp[1][0])+(a.dp[1][2]*b.dp[0][0]); x.ca+=a.ca+b.ca; x.ca2=a.ca2+b.ca2+(a.dp[0][0]*b.dp[2][2])+(a.dp[2][2]*b.dp[0][0]); for(int i=0;i<3;i++)for(int j=0;j<3;j++)x.dp[i][j]=a.dp[i][j]+b.dp[i][j]; return x; } path addvertex(point a,int i){ path x; for(int i=0;i<3;i++)for(int j=0;j<3;j++)x.dp[i][j]=a.dp[i][j]; x.ca=a.ca; if(F[i]==0){ x.ca+=a.dp[1][2]; x.dp[0][0]++; } else if(F[i]==2){ x.ca+=a.dp[1][0]; x.dp[2][2]++; } else{ x.ca+=a.ca2; x.dp[1][2]+=x.dp[2][2]; x.dp[1][0]+=x.dp[0][0]; x.dp[1][1]++; //cout<<i<<"YUHUH\n"; x.c++; } return x; } point addedge(path a){ point x; x.ca=a.ca; for(int i=0;i<3;i++)for(int j=0;j<3;j++)x.dp[i][j]=a.dp[i][j]; return x; } vector<path>Path; vector<point>Point; sttree stt; void update(int cur){ if(stt.T[cur]==Type::Vertex){ Path[cur]=vertex(cur); } if(stt.T[cur]==Type::Compress){ Path[cur]=compress(Path[stt.L[cur]],Path[stt.R[cur]]); } if(stt.T[cur]==Type::Rake){ Point[cur]=rake(Point[stt.L[cur]],Point[stt.R[cur]]); } if(stt.T[cur]==Type::AddEdge){ Point[cur]=addedge(Path[stt.L[cur]]); } if(stt.T[cur]==Type::AddVertex){ Path[cur]=addvertex(Point[stt.L[cur]],cur); } } void dfs(int cur){ if(cur==-1)return; dfs(stt.L[cur]); dfs(stt.R[cur]); update(cur); } vector<int>adj2[mxn+10]; void getadj(int cur,int p){ for(auto i:adj2[cur])if(i!=p){ adj[cur].pb(i); getadj(i,cur); } } void init(int32_t N, std::vector<int32_t> FF, std::vector<int32_t> U, std::vector<int32_t> V,int32_t Q) { n=N; for(int i=0;i<n-1;i++)adj2[U[i]].pb(V[i]),adj2[V[i]].pb(U[i]); getadj(0,-1); for(int i=0;i<n;i++)F[i]=FF[i]; Path.resize(4*n+1); Point.resize(4*n+1); stt.init(0); dfs(stt.stroot); } void change(int32_t x, int32_t y){ F[x]=y; while(x!=-1){ update(x); x=stt.P[x]; } } long long num_tours(){ return Path[stt.stroot].ca; }

Compilation message (stderr)

joitour.cpp: In function 'void setIO(std::string)':
joitour.cpp:24:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   24 |         freopen((name+".in").c_str(),"r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
joitour.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+".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...
#Verdict Execution timeMemoryGrader output
Fetching results...