Submission #978220

#TimeUsernameProblemLanguageResultExecution timeMemory
978220model_codeTricolor Lights (JOI24_tricolor)C++17
100 / 100
123 ms8288 KiB
//L=28 #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef __int128 lll; using ull = unsigned long long; typedef pair<ll,ll> pll; typedef vector<ll> vll; typedef vector<pll> vpll; #define mp make_pair #define pb push_back #define eb emplace_back #define fi first #define se second #define all(x) x.begin(),x.end() #define si(x) ll(x.size()) #define rep(i,n) for(ll i=0;i<n;i++) #define per(i,n) for(ll i=n-1;i>=0;i--) #define rng(i,l,r) for(ll i=l;i<r;i++) #define gnr(i,l,r) for(ll i=r-1;i>=l;i--) #define fore(i, a) for(auto &&i : a) #define fore2(a, b, v) for(auto &&[a, b] : v) #define fore3(a, b, c, v) for(auto &&[a, b, c] : v) #include "Anna.h" namespace{ vector<int> de_Bruijn(int typ){ //ternaries of 3 digits //except numbers whose digits are all (1 or 2) (ex. 121) //also exept //typ=0: //typ=1: 010,101 //typ=2: 000,010,101 //typ=3: 010,101,020,202 ll len=3; //make graph ll n=pow(3,len-1); vector<vector<pair<ll,ll> > >g(n); auto valid=[&](ll x){ //valid as an edge? if(typ>=1&&x==3)return 0; if(typ>=1&&x==9+1)return 0; if(typ==2&&x==0)return 0; if(typ==3&&x==2*3)return 0; if(typ==3&&x==2*9+2*1)return 0; rep(_,len){ if(x%3==0)return 1; x/=3; } return 0; }; rep(i,3*n)if(valid(i)){ ll x=i/3; ll y=i%n; g[x].eb(y,i%3); } // { // vector<int> cnt(n,0); // rep(i,n)rep(j,si(g[i]))cnt[g[i][j].first]++; // rep(i,n)if(cnt[i]!=si(g[i])){ // cout<<"invalid graph: degree sum is not 0"<<endl; // } // } //generate sequence (get an euler cycle of the graph) vector<int> ans; function<void(ll,ll)> dfs=[&](ll x,ll col){ while(si(g[x])){ auto [nxt,ncol]=g[x].back(); g[x].pop_back(); dfs(nxt,ncol); } ans.pb(col); }; ll start_vertex=0; dfs(start_vertex,-1); ans.pop_back(); reverse(all(ans)); return ans; } } pair<string,int> anna(int N,string S){ string str="RGB"; int B=9,L=28; const int TYP=4; string T; rep(i,N+B)T+='#'; ll id=0; //make 4 de_Bruijn-like sequences of period 19, 17, 16, 15 //they make a de_Bruijn-like sequence of period LCM(19,17,16,15) vector<int> seq[TYP]; rep(typ,TYP)seq[typ]=de_Bruijn(typ); rep(i,N/B+1){ //repeat blocks //control differnce of adjacent digits mod 3 //a block is: (?) * ? * ? * ? * (1 or 2) // ?: over control // *: fully under control (either 0,1,2) rep(typ,TYP){ //write de Bruijn_like sequences at *s rep(x,3)if(str[x]!=S[id]){ rep(y,3)if(str[y]!=S[id+1]){ if((x-y+3)%3==seq[typ][i%si(seq[typ])]){ T[id++]=str[x]; T[id++]=str[y]; x=y=3; } } } } rep(x,3)if(str[x]!=S[id]&&str[x]!=T[id-1]){ T[id++]=str[x]; break; } } while(si(T)>N)T.pop_back(); if(L>N)L=N; return {T,L}; }
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef __int128 lll; using ull = unsigned long long; typedef pair<ll,ll> pll; typedef vector<ll> vll; typedef vector<pll> vpll; #define mp make_pair #define pb push_back #define eb emplace_back #define fi first #define se second #define all(x) x.begin(),x.end() #define si(x) ll(x.size()) #define rep(i,n) for(ll i=0;i<n;i++) #define per(i,n) for(ll i=n-1;i>=0;i--) #define rng(i,l,r) for(ll i=l;i<r;i++) #define gnr(i,l,r) for(ll i=r-1;i>=l;i--) #define fore(i, a) for(auto &&i : a) #define fore2(a, b, v) for(auto &&[a, b] : v) #define fore3(a, b, c, v) for(auto &&[a, b, c] : v) #include "Bruno.h" namespace{ int N,L; const int B=9,TYP=4; //same as Anna vector<int> de_Bruijn(int typ){ //ternaries of 3 digits //except numbers whose digits are all (1 or 2) (ex. 121) //also exept //typ=0: //typ=1: 010,101 //typ=2: 000,010,101 //typ=3: 010,101,020,202 ll len=3; //make graph ll n=pow(3,len-1); vector<vector<pair<ll,ll> > >g(n); auto valid=[&](ll x){ //valid as an edge? if(typ>=1&&x==3)return 0; if(typ>=1&&x==9+1)return 0; if(typ==2&&x==0)return 0; if(typ==3&&x==2*3)return 0; if(typ==3&&x==2*9+2*1)return 0; rep(_,len){ if(x%3==0)return 1; x/=3; } return 0; }; rep(i,3*n)if(valid(i)){ ll x=i/3; ll y=i%n; g[x].eb(y,i%3); } // { // vector<int> cnt(n,0); // rep(i,n)rep(j,si(g[i]))cnt[g[i][j].first]++; // rep(i,n)if(cnt[i]!=si(g[i])){ // cout<<"invalid graph: degree sum is not 0"<<endl; // } // } //generate sequence (get an euler cycle of the graph) vector<int> ans; function<void(ll,ll)> dfs=[&](ll x,ll col){ while(si(g[x])){ auto [nxt,ncol]=g[x].back(); g[x].pop_back(); dfs(nxt,ncol); } ans.pb(col); }; ll start_vertex=0; dfs(start_vertex,-1); ans.pop_back(); reverse(all(ans)); return ans; } vector<int> seq[TYP]; map<ll,ll> rv[TYP]; map<tuple<ll,ll,ll,ll>,ll> block_id; } void init(int n,int l){ N=n,L=l; //pre-calculate the difference sequence Anna generates ll bruijn_len=3; rep(typ,TYP){ seq[typ]=de_Bruijn(typ); ll x=0; rep(i,si(seq[typ])+bruijn_len-1){ x%=(ll)pow(3,bruijn_len-1); x=x*3+seq[typ][i%si(seq[typ])]; if(i-(bruijn_len-1)>=0){ rv[typ][x]=i-(bruijn_len-1); } } } rep(i,N/B+1){ block_id[make_tuple(i%si(seq[0]),i%si(seq[1]),i%si(seq[2]),i%si(seq[3]))]=i; } } int bruno(string U){ string str="RGB"; if(N==L)return 1; //calculate difference sequence vll v; rep(i,L-1){ rep(x,3)if(str[x]==U[i]){ rep(y,3)if(str[y]==U[i+1]){ v.pb((x-y+3)%3); } } } int s; // s...where a block starts at { //for each remainder mod B(block size), see whether 0s exist in the given defference sequence (length L-1). //It can be "No" for only 0,2,4,6,8th places (cf. a block is: ? * ? * ? * ? * (1 or 2) ) //always "Yes" for 1,3,5,7th places, since we generated de_Bruijn-like sequences in that way //always "No" for 8th place. //we can determine which is the 8th place, seeing the distance parities of "No" places. vector<int> exzero(B,0); rep(i,si(v)){ exzero[i%B]|=v[i]==0; } vll nonzeros; rep(i,B)if(!exzero[i])nonzeros.pb(i); if(si(nonzeros)==1){ s=nonzeros[0]; } else{ s=nonzeros.back(); rep(i,si(nonzeros)-1){ if((nonzeros[i+1]-nonzeros[i])%2==1){ s=nonzeros[i]; break; } } } } //calculate block's place using pre-calculated dictionary (patterns -> number) vll pos; rep(typ,TYP){ ll x=0; rep(i,si(v))if(i%B==(s+2+2*typ)%B){ x=x*3+v[i]; } ll pos_=rv[typ][x]; if(s+2+2*typ-B<0)pos_=(pos_-1+si(seq[typ]))%si(seq[typ]); pos.pb(pos_); } ll res=block_id[make_tuple(pos[0],pos[1],pos[2],pos[3])]; return res*B+B-2-s+1; }
#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...