The 2024 ICPC Asia Hong Kong Regional Contest
题解:
https://files.cnblogs.com/files/clrs97/2024_Hong_Kong_Tutorial.pdf
Code:
A. General Symmetry
// floating point errors #pragma GCC optimize("Ofast,unroll-loops") // safe // #pragma GCC optimize("O3,unroll-loops") // doesn't work in yandex #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") // doesn't work in some judges // #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt,tune=native") // safe // #pragma GCC target("sse4.2,bmi,bmi2,lzcnt,popcnt") #include<iostream> #include<bitset> #include<algorithm> using namespace std; const int N=200005,V=1000,K=5; int n,m,k,i,l,r,a[N]; struct BIT{ unsigned long long v[(N>>6)+1]; bool get(int x)const{return v[x>>6]>>(x&63)&1;} void set(int x){v[x>>6]|=1ULL<<(x&63);} void operator^=(const BIT&o){for(int i=0;i<=m;i++)v[i]^=o.v[i];} void operator=(const BIT&o){for(int i=0;i<=m;i++)v[i]=o.v[i];} void shiftand(const BIT&o){ for(int i=0;i<m;i++)v[i]=((v[i]>>1)+((v[i+1]&1)<<63))&o.v[i]; v[m]=(v[m]>>1)&o.v[m]; } }occ[V+1],mask[V+1],f,save[(N>>K)+1]; inline int myabs(int x){return x>0?x:-x;} inline bool check(int l,int r){return myabs(a[l]-a[r])<=k;} inline int ask(int A,int B){ if(!check(A,B))return 0; int l=((B-1)>>K)+1,r=n>>K,mid,t=0; while(l<=r){ mid=(l+r)>>1; int d=(mid<<K)-B; if(A-d>=1&&save[mid].get(A-d))l=mid+1,t=d;else r=mid-1; } A-=t,B+=t; while(A>1&&B<n&&check(A-1,B+1))A--,B++; return B-A+1; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>n>>k; m=n>>6; for(i=1;i<=n;i++)cin>>a[i]; for(i=1;i<=n;i++)occ[a[i]].set(i); for(i=2;i<=V;i++)occ[i]^=occ[i-1]; for(i=1;i<=V;i++){ l=max(i-k,1); r=min(i+k,V); mask[i]=occ[r]; mask[i]^=occ[l-1]; } for(i=1;i<=n;i++){ m=i>>6; f.shiftand(mask[a[i]]); f.set(i); if(i>1&&check(i-1,i))f.set(i-1); if(!(i&((1<<K)-1)))save[i>>K]=f; } for(i=1;i<=n;i++){ cout<<ask(i,i); if(i<n)cout<<" ";else cout<<"\n"; } for(i=1;i<n;i++){ cout<<ask(i,i+1); if(i+1<n)cout<<" ";else cout<<"\n"; } }
B. Defeat the Enemies
#include <bits/stdc++.h> using namespace std; int n , m; int a[500005] , b[500005]; const int mod = 998244353; typedef long long ll; void upd(int &x,int y) { ((x += y) >= mod ? (x -= mod) : 0) ; } int c[105] , k; void solv() { cin >> n >> m; int mx = 0; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= n;i++) cin >> b[i]; cin >> k; for(int i = 1;i <= k;i++) cin >> c[i]; for(int i = 1;i <= n;i++) mx = max(mx , a[i] + b[i]) ; vector<int> h(mx + k*2 + 1 , 1e9) ; for(int i = 1;i <= n;i++) { int x = mx - (a[i] + b[i]) ; h[b[i] - 1] = min(h[b[i] - 1] , b[i] + x) ; } for(int i = mx + k*2 - 1; i >= 0;i--) h[i] = min(h[i] , h[i + 1]) ; vector<ll> f(mx + k*2 + 1) ; vector<int> g(mx + k*2 + 1) ; ll ans = 1e18; int cnt = 0; for(int d = 0 ; d <= k * 2 - 2 ; d++) { for(auto &x : f) x = 1e18; for(auto &x : g) x = 0; f[0] = 0; g[0] = 1; for(int i = 0 ;i < mx + d ; i++) { for(int j = 1 ; j <= k && i + j <= mx + d && i + j <= h[i] + d ; j++) { if(f[i + j] > f[i] + c[j]) { f[i + j] = f[i] + c[j] ; g[i + j] = g[i] ; } else if(f[i + j] == f[i] + c[j]) { upd(g[i + j] , g[i]) ; } } } if(f[mx + d] < ans) { ans = f[mx + d]; cnt = g[mx + d] ; } else if(f[mx + d] == ans) upd(cnt , g[mx + d]) ; } cout << ans <<' ' << cnt << '\n' ; return ; } int main() { ios::sync_with_stdio(false) ; cin.tie(0) ; int t ; cin >> t; while(t--) solv() ; }
C. The Story of Emperor Bie
#include <bits/stdc++.h> using namespace std; int p[500005]; int n ; void solv() { cin >> n; for(int i = 1;i <= n;i++) cin >> p[i] ; int mx = *max_element(p + 1 , p + n + 1) ; for(int i = 1;i <= n;i++) { if(p[i] == mx) cout << i <<' ' ; } cout << '\n'; } int main() { ios::sync_with_stdio(false) ; cin.tie(0) ; int t ; cin >> t; while(t--) solv() ; }
D. Master of Both VI
#include<bits/stdc++.h> using namespace std; using ll=int; const int N=5e5+1e3+7,Q=3e5+1e3+7; int n,q,fa[N]; vector<int> g[N]; struct Mat { ll f00,f01,f10,f11; }; struct Vec { ll f0,f1; ll gmn(){return min(f0,f1);} }; Vec operator *(const Mat &a,const Vec &b) { return {min(a.f00+b.f0,a.f01+b.f1),min(a.f10+b.f0,a.f11+b.f1)}; } Mat operator *(const Mat &a,const Mat &b) { return {min(a.f00+b.f00,a.f01+b.f10), min(a.f00+b.f01,a.f01+b.f11), min(a.f10+b.f00,a.f11+b.f10), min(a.f10+b.f01,a.f11+b.f11)}; } struct T { int ls,rs,cnt; Mat v; }t[Q*2*19]; int st[20][N],dfn[N],dc; void dfs(int x,int f) { fa[x]=f; st[0][dc]=f; dfn[x]=++dc; for(auto v:g[x]) { if(v==f) continue; dfs(v,x); } } int mn(int x,int y) { return dfn[x]<dfn[y]?x:y; } int lca(int x,int y) { if(dfn[x]>dfn[y]) swap(x,y); int k=__lg(dfn[y]-dfn[x]); return x!=y?mn(st[k][dfn[x]],st[k][dfn[y]-(1<<k)]):x; } vector<int> add[N],qr[N]; int rt[N],cnt; ll w[Q]; void update(int x) { t[x].cnt=t[t[x].ls].cnt+t[t[x].rs].cnt; if(!t[x].cnt) return; else if(!t[t[x].ls].cnt) t[x].v=t[t[x].rs].v; else if(!t[t[x].rs].cnt) t[x].v=t[t[x].ls].v; else t[x].v=t[t[x].ls].v*t[t[x].rs].v; } Mat Z={0,(ll)1e9,(ll)1e9,0}; void ins(int &x,int l,int r,int p,int v) { if(!x) x=++cnt; if(l==r) { if(v>0) { t[x].cnt=1; t[x].v={w[l]*2,w[l],w[l]*2,w[l]*2}; } else { t[x].cnt=0; t[x].v=Z; } return; } int mid=(l+r)>>1; if(p<=mid) ins(t[x].ls,l,mid,p,v); else ins(t[x].rs,mid+1,r,p,v); update(x); } int merge(int x,int y,int l,int r) { if(!x||!y) return x+y; if(l==r) return t[x].cnt?x:y; int mid=(l+r)>>1; t[x].ls=merge(t[x].ls,t[y].ls,l,mid); t[x].rs=merge(t[x].rs,t[y].rs,mid+1,r); update(x); return x; } int fd; int qry(int x,int l,int r,int p,Vec &u,ll h) { if(r<=p) { auto ru=t[x].v*u; if(ru.gmn()<h) { u=ru; return t[x].cnt; } } if(l==r) { fd=1; return 0; } int mid=(l+r)>>1; int ret=0; if(p>mid&&t[t[x].rs].cnt) ret=qry(t[x].rs,mid+1,r,p,u,h); if(!t[t[x].ls].cnt||fd) return ret; ret+=qry(t[x].ls,l,mid,p,u,h); return ret; } int ans[Q]; void getans(int x) { for(auto v:g[x]) { if(v==fa[x]) continue; getans(v); rt[x]=merge(rt[x],rt[v],1,q); } for(auto id:add[x]) ins(rt[x],1,q,abs(id),id); for(auto id:qr[x]) { Vec u={0,0}; fd=0; ans[id]=qry(rt[x],1,q,id,u,w[id]*2); } } signed main() { ios::sync_with_stdio(false); cin.tie(0); t[0].v=Z; cin>>n>>q; for(int i=1;i<n;i++) { int u,v; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } dfs(1,0); for(int i=1;i<20;i++) for(int j=1;j+(1<<i)-1<n;j++) st[i][j]=mn(st[i-1][j],st[i-1][j+(1<<i-1)]); memset(ans,-1,sizeof(ans)); for(int i=1;i<=q;i++) { string op; cin>>op; if(op[0]=='A') { int u,v; cin>>u>>v>>w[i]; int p=lca(u,v); add[u].push_back(i); add[v].push_back(i); add[fa[p]].push_back(-i); } else { int x; cin>>x>>w[i]; qr[x].push_back(i); } } getans(1); for(int i=1;i<=q;i++) if(ans[i]!=-1) cout<<ans[i]<<"\n"; }
E. Concave Hull
#include<bits/stdc++.h> using namespace std; const int N=2505; typedef long long ll; const int mod=1e9+7; int n,ans; bool on[N]; struct Point{ int x,y,id; Point(int _x=0,int _y=0,int _id=-1):x(_x),y(_y),id(_id){} friend Point operator - (const Point &a,const Point &b){ return Point(a.x-b.x,a.y-b.y); } friend Point operator + (const Point &a,const Point &b){ return Point(a.x+b.x,a.y+b.y); } friend ll operator % (const Point &a,const Point &b){ return 1LL*a.x*b.y-1LL*a.y*b.x; } friend bool operator < (const Point &a,const Point &b){ return a.y==b.y?a.x<b.x:a.y<b.y; } inline ll len2(){ return 1LL*x*x+1LL*y*y; } inline int Quad(){ return y>0||(y==0&&x>0); } }; typedef vector<Point> poly; inline bool Left(Point a,Point b){ return b%a>0; } poly A; int Area(poly A){ int m=A.size(); int tot=0; for(int i=0;i<m;++i){ tot=(tot+(A[i]%A[(i+1)%m]))%mod; } tot=(tot+mod)%mod; return tot; } void calc(poly B){ sort(B.begin(),B.end(),[&](Point a,Point b){ return a.Quad()^b.Quad()?a.Quad()>b.Quad():Left(b,a); }); for(int i=0;i<(int)B.size();++i){ if(on[B[i].id]){ rotate(B.begin(),B.begin()+i,B.end()); break; } } B.push_back(B[0]); int cnt=0; poly st; ll now=0; for(auto &p:B){ while(st.size()>1&&Left(st.back()-st[st.size()-2],p-st[st.size()-2])){ now=(now-(st[st.size()-2]%st.back()))%mod; st.pop_back(); } if(st.size()>0){ now=(now+(st.back()%p))%mod; } st.push_back(p); ++cnt; if(on[p.id]){ if(st.size()>1){ ans=(ans+cnt*((st[st.size()-2]%st.back())%mod))%mod; } cnt=0; now=0; } ans=(ans-now)%mod; } reverse(B.begin(),B.end()); now=0; for(auto &p:B){ while(st.size()>1&&Left(p-st[st.size()-2],st.back()-st[st.size()-2])){ now=(now-(st.back()%st[st.size()-2]))%mod; st.pop_back(); } if(st.size()>0){ now=(now+(p%st.back()))%mod; } st.push_back(p); if(on[p.id]){ now=0; } ans=(ans-now)%mod; } } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin>>n; A.resize(n); for(int i=0;i<n;++i){ cin>>A[i].x>>A[i].y; A[i].id=i; } Point LTL=*min_element(A.begin(),A.end()); sort(A.begin(),A.end(),[&](Point a,Point b){ a=a-LTL; b=b-LTL; if((a%b)==0)return a.len2()<b.len2(); return Left(b,a); }); poly st; for(auto &p:A){ while(st.size()>1&&Left(st.back()-st[st.size()-2],p-st[st.size()-2])){ st.pop_back(); } st.push_back(p); } for(auto &p:st){ on[p.id]=1; } for(auto &t:A){ if(on[t.id])continue; poly B; for(auto &p:A){ if(p.id!=t.id){ B.push_back(p-t); B.back().id=p.id; } } calc(B); } ans=(ans+mod)%mod; ans=(1LL*(n-1)*(n-((int)st.size()))%mod*Area(st)%mod-ans+mod)%mod; cout<<ans<<'\n'; return 0; }
F. Money Game 2
#include<bits/stdc++.h> using namespace std; using pii=pair<int,int>; const int N=5e5+1e3+7; int T,n,a[N]; vector<pii> L[N],R[N]; int chk(int a,int b,int c,int d) { if(a>b) return chk(a,n-1,c,d)&&chk(0,b,c,d); if(c>d) return chk(a,b,c,n-1)&&chk(a,b,0,d); return a>d||c>b; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>T; while(T--) { cin>>n; for(int i=0;i<n;i++) cin>>a[i],L[i].clear(),R[i].clear(); if(n==1) { cout<<a[0]<<"\n"; continue; } for(int r=0;r<n*2;r++) { int i=r%n; auto tmp=L[(i+n-1)%n]; if(tmp.size()&&tmp.begin()->second==i) tmp.erase(tmp.begin()); tmp.push_back({0,i}); L[i].clear(); reverse(tmp.begin(),tmp.end()); for(auto [x,y]:tmp) { if(!L[i].size()||x/2+a[i]!=L[i].back().first) L[i].push_back({x/2+a[i],y}); } reverse(L[i].begin(),L[i].end()); } for(int r=n*2-1;r>=0;r--) { int i=r%n; auto tmp=R[(i+1)%n]; if(tmp.size()&&tmp.begin()->second==i) tmp.erase(tmp.begin()); tmp.push_back({0,i}); R[i].clear(); reverse(tmp.begin(),tmp.end()); for(auto [x,y]:tmp) { if(!R[i].size()||x/2+a[i]!=R[i].back().first) R[i].push_back({x/2+a[i],y}); } reverse(R[i].begin(),R[i].end()); } for(int i=0;i<n;i++) { long long ans=0; ans=max(ans,1ll*R[i][0].first); for(int j=0,k=(int)R[i].size()-1;j+1<L[i].size();j++) { while(k>0&&chk(L[i][j].second,(i+n-1)%n,(i+1)%n,R[i][k-1].second)) k--; ans=max(ans,1ll*R[i][k].first+L[i][j].first-a[i]); } cout<<ans<<" \n"[i+1==n]; } } }
G. Yelkrab
#include<bits/stdc++.h> using namespace std; const int N=1e6+1e3+7; int T,n,sz[N]; vector<int> fac[N]; int son[N][26],ans[N]; string s[N]; int t; int main() { ios::sync_with_stdio(false); cin.tie(0); for(int i=1;i<=500000;i++) for(int j=i;j<=500000;j+=i) fac[j].push_back(i); cin>>T; while(T--) { cin>>n; memset(son[0],-1,sizeof(son[0])); t=0; for(int i=1;i<=n;i++) ans[i]=0; int ANS=0; for(int i=1;i<=n;i++) { string s; cin>>s; int x=0; for(auto c:s) { c-='a'; if(son[x][c]==-1) { son[x][c]=++t; sz[t]=0; memset(son[t],-1,sizeof(son[t])); } x=son[x][c]; sz[x]++; for(auto p:fac[sz[x]]) { ANS^=ans[p]*p; ans[p]++; ANS^=ans[p]*p; } } cout<<ANS<<" \n"[i==n]; } } }
H. Mah-jong
#include <bits/stdc++.h> using namespace std; const int D = 8; vector<int> g(D - 2) ; typedef vector<int> vi; typedef long long ll; vector<pair<vi,vi> > t; void dfs(int u) { if(u == D - 2) { vector<int> v(D) , lm(D); for(int i = 0;i < D - 2;i++) { v[i] += g[i]; v[i + 1] += g[i]; v[i + 2] += g[i]; } for(int i = 0;i < D;i++) { lm[i] = v[i] ; v[i] %= 3; } t.push_back({v , lm}) ; return ; } for(int i = 0;i < 3;i++) { g[u] = i; dfs(u + 1); } } int n; int a[100005]; int pre[100005][D]; int fir[D][100005]; const int D3 = 6561; typedef pair<int,int> pii; vector<int> tr(D); void solv() { cin >> n; for(int i = 1;i <= n;i++) { cin >> a[i] ; a[i]-- ; } for(int i = 1;i <= n;i++ ) { for(int j = 0;j < D;j++) { pre[i][j] = pre[i - 1][j]; } fir[a[i]][pre[i][a[i]]] = i - 1; /// for num ai , the last one with <= j pre[i][a[i]]++ ; } for(int j = 0;j < D;j++) fir[j][pre[n][j]] = n; ll ans = 0; for(auto &[v,lm] : t) { vector<int> pre(D) , pv(D); for(int j = 0;j < D;j++) pre[j] = ::pre[n][j] ; int d = 0; for(int j = 0;j < D;j++) { pv[j] = (pre[j] - v[j] + 3) % 3; d += pv[j] * tr[j] ; } vector<pii> qry; int r = n + 1; for(int j = 0;j < D;j++) { if(pre[j] < lm[j]) r = -1; else r = min(r , fir[j][pre[j] - lm[j]]) ; } if(r == -1) continue ; for(int i = n;i >= 1;i--) { r = min(r , i - 1); if(r != -1) { qry.push_back({r , d}) ; } d -= pv[a[i]] * tr[a[i]] ; pv[a[i]]-- ; if(pv[a[i]] < 0) pv[a[i]] += 3; d += pv[a[i]] * tr[a[i]] ; pre[a[i]]-- ; if(pre[a[i]] < lm[a[i]]) {r = -1; break ;} else r = min(r , fir[a[i]][pre[a[i]] - lm[a[i]]]) ; } reverse(qry.begin() , qry.end()) ; vector<int> sum(D) , num(D3); int hs = 0; int nxt = 0; for(int i = 0;i <= n;i++) { if(i) { hs -= sum[a[i]] * tr[a[i]] ; sum[a[i]] = (sum[a[i]] + 1) % 3; hs += sum[a[i]] * tr[a[i]] ; } num[hs]++ ; while(nxt < qry.size() && qry[nxt].first <= i) { ans += num[qry[nxt].second] ; nxt++ ; } } } cout << ans << '\n'; return ; } int main() { ios::sync_with_stdio(false) ; cin.tie(0) ; dfs(0) ; tr[0] = 1; for(int i = 1;i < D;i++) tr[i] = tr[i - 1] * 3; int t ; cin >> t; while(t--) solv() ; }
I. Ma Meilleure Ennemie
#include<bits/stdc++.h> using namespace std; #define int long long namespace Pollard_Rho { mt19937 rd(time(0)); inline int A(int x, int p) { return x >= p ? x - p : x; } inline int D(int x, int p) { return x < 0 ? x + p : x; } inline int Mul(int x, int y, int p) { return D(A(x * y - (int)((long double)x * y / p) * p, p), p); } inline int Qpow(int x, int y, int p) { int ans = 1; for (; y; y >>= 1, x = Mul(x, x, p)) if (y & 1) ans = Mul(ans, x, p); return ans; } inline bool Mr(int x, int b) { int k = x - 1; while (k) { int cur = Qpow(b % x, k, x); if (cur != 1 && cur != x - 1) return 0; if ((k & 1) || cur == x - 1) return 1; k >>= 1; } return 1; } int p[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022}; inline bool IsPrime(int n) { if (n <= 1 || n == 46856248255981ll) return 0; for(int i = 0; i < 7; i++) { if(p[i] % n == 0) continue; if(n == p[i]) return 1; if(!Mr(n, p[i])) return 0; } return 1; // if (n == 2 || n == 61) return 1; // return Mr(n, 2) && Mr(n, 61); } inline int Pr(int x) { int s = 0, t = 0, c = rd() % (x - 1) + 1; int stp = 0, goal = 1; int val = 1; for (goal = 1; ; goal <<= 1, s = t, val = 1) { for (stp = 1; stp <= goal; ++stp) { t = A(Mul(t, t, x) + c, x); val = Mul(val, abs(t - s), x); if ((stp & 127) == 0) { int d = __gcd(val, x); if (d > 1) return d; } } int d = __gcd(val, x); if (d > 1) return d; } } inline void Divide(int n, map<int, int> &ans) { if (n <= 1) return; if (IsPrime(n)) return void(++ans[n]); int x = n; while (x == n) x = Pr(n); Divide(x, ans); Divide(n / x, ans); } inline map<int, int> Factor(int x) { map<int, int> ans; Divide(x, ans); return ans; } } int n, m; vector<int> fac, id, wid; const int P = 998244353; vector<int> prod; int qpow(int a, int b) { b %= P - 1; int ret = 1; while(b) { if(b & 1) ret = ret * a % P; b >>= 1; a = a * a % P; } return ret; } signed main() { cin >> n >> m; if(n == 1) { cout << m % P << "\n"; return 0; } auto tmp = Pollard_Rho::Factor(n); for(auto [x, y] : tmp) fac.push_back(x); prod.resize(1 << fac.size(), 1); wid.resize(prod.size()); id.resize(fac.size()); id[0] = 1; for(int i = 1; i < fac.size(); i += 1) id[i] = id[i - 1] * (tmp[fac[i - 1]] + 1); for(int S = 0; S < (1 << fac.size()); S += 1) for(int i = 0; i < fac.size(); i += 1) if(S >> i & 1) prod[S] *= fac[i], wid[S] += id[i]; int ID = 0; for(int i = 0; i < fac.size(); i += 1) ID += id[i] * tmp[fac[i]]; vector<int> dp(ID + 1, 0), wn(ID + 1, 0), wm(ID + 1, 0); wn[ID] = n, wm[ID] = m; for(int i = ID; i >= 0; i -= 1) { for(int j = 0; j < fac.size(); j += 1) { if(wn[i] % fac[j] == 0) { wn[i - id[j]] = wn[i] / fac[j]; wm[i - id[j]] = wm[i] / fac[j]; } } } for(int i = 0; i <= ID; i += 1) { int T = 0; for(int j = 0; j < fac.size(); j += 1) if(wn[i] % fac[j] == 0) T ^= 1 << j; int ret = 0; for(int S = T;;S = (S - 1) & T) { int mu = __builtin_parity(S) ? -1 : 1; int e = prod[S]; ret += mu * (wm[i] / e); if(S) { ret -= mu * qpow(dp[i - wid[S]], e); } if(!S) break; } dp[i] = (ret % P + P) % P; } cout << dp[ID] << "\n"; return 0; }
J. Reconstruction
#include<bits/stdc++.h> using namespace std; const int N=500050; int n,ok[N]; vector<int> G[N],H[N]; struct Union_Set{ int f[N]; void init(int n){ for(int i=1;i<=n;++i){ f[i]=i; } } inline int getf(int x){ return f[x]==x?x:f[x]=getf(f[x]); } }S; int vis[N]; int dfs(int u,int fa){ for(auto v:H[u]){ if(v==fa)continue; int x=dfs(v,u); if(x)return x; } for(auto v:G[u]){ vis[S.getf(v)]=u; } for(auto v:H[u]){ if(v==fa)continue; if(vis[v]!=u)return v; S.f[S.getf(v)]=u; } return 0; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin>>n; for(int i=1;i<n;++i){ int u,v; cin>>u>>v; G[u].push_back(v); G[v].push_back(u); } for(int i=1;i<n;++i){ int u,v; cin>>u>>v; H[u].push_back(v); H[v].push_back(u); } S.init(n); int rt=dfs(1,0),OK=0; if(!rt)rt=1,OK=1; memset(vis,0,sizeof(vis)); S.init(n); if(OK||!dfs(rt,0)){ memset(vis,0,sizeof(vis)); queue<int> q; q.push(rt); ok[rt]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(auto v:G[u]){ vis[v]=u; } for(auto v:H[u]){ if(vis[v]&&!ok[v]){ ok[v]=1; q.push(v); } } } } for(int i=1;i<=n;++i){ cout<<ok[i]; } cout<<'\n'; return 0; }
K. LR String
#include <bits/stdc++.h> using namespace std; string s ; int q; const int N = 5e5 + 5; int nxt[N][2]; const int inf = 1e9; void solv() { cin >> s >> q; int c[2] = {inf , inf} ; for(int i= s.size() - 1;i >= 0;i--) { nxt[i][0] = c[0]; nxt[i][1] = c[1]; if(s[i] == 'L') c[0] = i; else c[1] = i; } while(q--) { string t ; cin >> t; if(s[0] == 'L' && t[0] != 'L') { cout << "NO\n"; continue ; } if(s.back() == 'R' && t.back() != 'R') { cout << "NO\n" ; continue ; } bool ff = 1; int u = (t[0] == 'L' ? c[0] : c[1]); for(int i = 1;i < t.size();i++) { if(u >= s.size()) { ff = 0 ; break ; } if(t[i] == 'L') u = nxt[u][0]; else u = nxt[u][1] ; if(u >= s.size()) { ff = 0 ; break ; } } cout << (ff ? "YES\n" : "NO\n") ; } return ; } int main() { ios::sync_with_stdio(false) ; cin.tie(0) ; int t ; cin >> t; while(t--) solv() ; }
L. Flipping Paths
#include<bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); int T; cin>>T; while(T--) { int n,m; cin>>n>>m; vector<string> s(n+5); for(int i=1;i<=n;i++) { string t; cin>>t; s[i]=' '+t; } if(n==1 and m==1) { cout<<"YES\n0\n"; continue; } if(n==3 and m==3 and s[1]==" WBB" and s[2]==" BWB" and s[3]==" BBW") { cout<<"YES\n2\nRRDD\nDDRR\n"; continue; } if(n==2 and m==2 and s[1]==" BB" and s[2]==" BB") { cout<<"YES\n0\n"; continue; } if(n==1 and m==5 and s[1]==" WWWWW") { cout<<"YES\n0\n"; continue; } vector<string> ans; int ok=0; auto tmp=s; auto flip=[&](char &ch){ch='B'+'W'-ch;}; for(auto ch:"BW") { s=tmp; ans.clear(); for(int diag=m-2;diag>=1-n;diag--)//y-x { string op; int x=1,y=1; while(y-x<diag)flip(s[x][y]),y++,op+='R'; while(y-x>diag)flip(s[x][y]),x++,op+='D'; while(x<n and y<m) { if(s[x][y+1]!=ch) { flip(s[x][y]),y++,op+='R'; flip(s[x][y]),x++,op+='D'; } else { flip(s[x][y]),x++,op+='D'; flip(s[x][y]),y++,op+='R'; } } while(y<m)flip(s[x][y]),y++,op+='R'; while(x<n)flip(s[x][y]),x++,op+='D'; flip(s[x][y]); ans.push_back(op); if(diag<=2-n) { int done=1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(s[i][j]!=ch) done=0; } } if(done) { ok=1; break; } } } if(ok)break; } if(ok) { cout<<"YES\n"<<ans.size()<<endl; for(auto row:ans) cout<<row<<endl; } else { cout<<"NO\n"; } } return 0; }
M. Godzilla
#include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef pair<int,int>P; typedef unsigned short U; const int N=77,M=N*2,K=8,CE=N*N; int n,m,ce,i,j,optd,optv,opt[4],f[M]; int maxd[4],two[4],twoedges[4],edge[3][3][4][2],extra[3][4]; struct E{int x,y,d,v;bool ban;}e[CE]; struct Basis{ int f,s,d,v; bool oncircle,del; }basis[M]; vector<int>adj[M]; int dfn,st[M],en[M],ccom,at[M],root[M],cir[M],delid[3]; struct Ranges{ vector<P>seg; int r,nxt; void init(int _l,int _r){ seg.clear(); r=_r; nxt=_l; } void append(int l,int r){ if(nxt<l)seg.emplace_back(P(nxt,l-1)); nxt=r+1; } void finish(){ if(nxt>r)return; seg.emplace_back(P(nxt,r)); } bool find(int x)const{ for(const auto&it:seg)if(it.first<=x&&x<=it.second)return 1; return 0; } void addtotree(vector<P>&v){ for(const auto&it:seg)v.emplace_back(it); } }; U top[4],top2[4][2];int Log[M]; inline void upu(U&a,U b){a<b?(a=b):0;} struct RMQ{ U f[K][M][4][2]; void init(){ for(int i=1;i<=n;i++)for(int j=0;j<4;j++)for(int k=0;k<2;k++)f[0][i][j][k]=0; } void build(){ for(int i=1;(1<<i)<=n;i++)for(int j=1;j+(1<<i)-1<=n;j++)for(int k=0;k<4;k++){ const auto&A=f[i-1][j][k]; const auto&B=f[i-1][j+(1<<(i-1))][k]; auto&C=f[i][j][k]; if(A[0]>B[0]){ C[0]=A[0]; C[1]=max(A[1],B[0]); }else if(A[0]<B[0]){ C[0]=B[0]; C[1]=max(A[0],B[1]); }else{ C[0]=A[0]; C[1]=max(A[1],B[1]); } } } void fetchtop(const P&seg)const{ int k=Log[seg.second-seg.first+1]; const auto&L=f[k][seg.first]; const auto&R=f[k][seg.second-(1<<k)+1]; for(int i=0;i<4;i++){ upu(top[i],L[i][0]); upu(top[i],R[i][0]); } } void fetchtop2(const P&seg)const{ int k=Log[seg.second-seg.first+1]; const auto&L=f[k][seg.first]; const auto&R=f[k][seg.second-(1<<k)+1]; for(int i=0;i<4;i++){ const auto&A=L[i]; const auto&B=R[i]; auto&C=top2[i]; if(C[0]>=A[0]&&C[0]>=B[0]){ upu(C[1],A[A[0]==C[0]]); upu(C[1],B[B[0]==C[0]]); }else if(C[0]>=A[0]){ C[1]=max(C[0],B[1]); C[0]=B[0]; }else if(C[0]>=B[0]){ C[1]=max(C[0],A[1]); C[0]=A[0]; }else if(A[0]>B[0]){ C[1]=max(C[0],A[1]); upu(C[1],B[0]); C[0]=A[0]; }else if(A[0]<B[0]){ C[1]=max(C[0],B[1]); upu(C[1],A[0]); C[0]=B[0]; }else{ C[1]=max(C[0],A[1]); upu(C[1],B[1]); C[0]=A[0]; } } } }; vector<RMQ>rmq[M]; inline bool cmpe(const E&a,const E&b){return a.d<b.d;} int F(int x){return f[x]==x?x:f[x]=F(f[x]);} inline void up(int&a,int b){a<b?(a=b):0;} inline void solve2edges(int A,int B){ int i,j; for(i=0;i<4;i++)twoedges[i]=0; for(i=0;i<4;i++)if(edge[A][B][i][0]) for(j=0;j<=i;j++)if(edge[A][B][j][i==j]) up(twoedges[(i+j)&3],edge[A][B][i][0]+edge[A][B][j][i==j]); } inline void solve2components(int A,int B){ int i,j; solve2edges(A,B); static int one[4]; for(i=0;i<4;i++){ one[i]=max(extra[A][i],extra[B][i]); two[i]=twoedges[i]; } for(i=0;i<4;i++)if(extra[A][i]) for(j=0;j<4;j++)if(extra[B][j]) up(two[(i+j)&3],extra[A][i]+extra[B][j]); for(i=0;i<4;i++)if(edge[A][B][i][0]) for(j=0;j<4;j++)if(one[j]) up(two[(i+j)&3],edge[A][B][i][0]+one[j]); } inline bool cmpv(int x,int y){return st[x]<st[y];} inline void solve(int cntdel){ int i,j,k,x,y; static int T,lastcom[M]; T++; static vector<int>poolcom; poolcom.clear(); for(i=0;i<cntdel;i++){ int o=delid[i]; x=basis[o].s; y=at[x]; if(lastcom[y]!=T){ lastcom[y]=T; poolcom.emplace_back(y); } } int ctree=0; static vector<P>tree[3]; for(i=0;i<cntdel;i++)tree[i].clear(); for(const auto&x:poolcom){ int S=root[x]; int L=st[S],R=en[S]; int pos=cir[x]?st[basis[cir[x]].s]:0; static int pool[4]; pool[0]=S; int cp=1; for(j=0;j<cntdel;j++)if(!basis[delid[j]].oncircle){ y=basis[delid[j]].s; if(at[y]==x)pool[cp++]=y; } sort(pool,pool+cp,cmpv); static int q[4]; int top=0; q[0]=0; static Ranges ranges[4]; ranges[0].init(L,R); for(i=1;i<cp;i++){ y=pool[i]; while(en[pool[q[top]]]<st[y])top--; ranges[q[top]].append(st[y],en[y]); q[++top]=i; ranges[i].init(st[y],en[y]); } for(i=0;i<cp;i++)ranges[i].finish(); if(pos&&!basis[cir[x]].del){ for(i=0;i<cp;i++)if(ranges[i].find(pos))break; if(!i)for(j=1;j<cp;j++)ranges[j].addtotree(tree[ctree++]); else{ ranges[0].addtotree(tree[ctree]); ranges[i].addtotree(tree[ctree]); sort(tree[ctree].begin(),tree[ctree].end()); ctree++; for(j=1;j<cp;j++)if(j!=i)ranges[j].addtotree(tree[ctree++]); } }else for(j=0;j<cp;j++)ranges[j].addtotree(tree[ctree++]); } static vector<P>all,outer; all.clear(); outer.clear(); for(i=0;i<ctree;i++)for(const auto&it:tree[i])all.emplace_back(it); sort(all.begin(),all.end()); int r=0; for(const auto&it:all){ if(r+1<it.first)outer.emplace_back(P(r+1,it.first-1)); up(r,it.second); } if(r<n)outer.emplace_back(P(r+1,n)); for(i=0;i<ctree;i++){ for(j=0;j<4;j++)top[j]=0; for(const auto&A:tree[i]){ const auto&ds=rmq[A.second][A.first]; for(const auto&B:tree[i]){ ds.fetchtop(B); if(B.first==A.first)break; } for(const auto&B:outer)ds.fetchtop(B); } for(j=0;j<4;j++)extra[i][j]=e[top[j]].d; for(j=i+1;j<ctree;j++){ for(k=0;k<4;k++)for(x=0;x<2;x++)top2[k][x]=0; for(const auto&A:tree[i]){ const auto&ds=rmq[A.second][A.first]; for(const auto&B:tree[j])ds.fetchtop2(B); } for(k=0;k<4;k++)for(x=0;x<2;x++){ int id=top2[k][x]; edge[i][j][k][x]=edge[j][i][k][x]=e[id].d; } } } if(ctree==1){ for(i=0;i<4;i++)maxd[i]=extra[0][i]; return; } if(ctree==2){ solve2components(0,1); for(i=0;i<4;i++)maxd[i]=two[i]; return; } for(i=0;i<4;i++)maxd[i]=0; for(i=0;i<4;i++)if(edge[0][1][i][0]) for(j=0;j<4;j++)if(edge[0][2][j][0]) for(k=0;k<4;k++)if(edge[1][2][k][0]) up(maxd[(i+j+k)&3],edge[0][1][i][0]+edge[0][2][j][0]+edge[1][2][k][0]); static int common[4]; for(i=0;i<4;i++){ common[i]=0; for(j=0;j<3;j++)up(common[i],extra[j][i]); } for(int S=0;S<3;S++){ int A=(S+1)%3,B=(S+2)%3; solve2components(A,B); for(i=0;i<4;i++)if(two[i]) for(j=0;j<4;j++)if(extra[S][j]) up(maxd[(i+j)&3],two[i]+extra[S][j]); for(i=0;i<4;i++)if(edge[S][A][i][0]) for(j=0;j<4;j++)if(edge[S][B][j][0]) for(k=0;k<4;k++)if(common[k]) up(maxd[(i+j+k)&3],edge[S][A][i][0]+edge[S][B][j][0]+common[k]); for(int _=0;_<2;_++){ solve2edges(S,A); for(i=0;i<4;i++)if(twoedges[i]) for(j=0;j<4;j++)if(edge[S][B][j][0]) up(maxd[(i+j)&3],twoedges[i]+edge[S][B][j][0]); swap(A,B); } } } void dfs(int x,int y){ at[x]=ccom; st[x]=++dfn; for(const auto&id:adj[x]){ int u=basis[id].f^basis[id].s^x; if(u==y)continue; if(u!=basis[id].s)swap(basis[id].f,basis[id].s); dfs(u,x); } en[x]=dfn; } inline void newcom(int S){ root[++ccom]=S; dfs(S,0); } void search(int o,int x){ if(o){ solve(o); for(int i=0;i<4;i++)if(maxd[i])up(opt[(optv+i)&3],optd+maxd[i]); } if(o==3)return; for(;x<=n;x++){ optd-=basis[x].d; (optv+=4-basis[x].v)&=3; basis[x].del=1; delid[o]=x; search(o+1,x+1); optd+=basis[x].d; (optv+=basis[x].v)&=3; basis[x].del=0; } } int main(){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++)for(j=1;j<=m;j++){ e[++ce].x=i; e[ce].y=j+n; scanf("%d",&e[ce].d); } ce=0; for(i=1;i<=n;i++)for(j=1;j<=m;j++){ scanf("%d",&e[++ce].v); e[ce].v&=3; } n+=m; sort(e+1,e+ce+1,cmpe); static bool g[M]; for(i=1;i<=n;i++)f[i]=i; m=0; for(i=ce;i;i--){ int x=F(e[i].x),y=F(e[i].y); if(g[x]&&g[y])continue; ++m; basis[m].f=e[i].x; basis[m].s=e[i].y; basis[m].d=e[i].d; basis[m].v=e[i].v; e[i].ban=1; optd+=e[i].d; (optv+=e[i].v)&=3; if(x==y){ g[x]=1; basis[m].oncircle=1; }else{ f[x]=y; g[y]|=g[x]; adj[e[i].x].emplace_back(m); adj[e[i].y].emplace_back(m); } } opt[optv]=optd; for(i=1;i<=n;i++)if(basis[i].oncircle){ newcom(basis[i].f); cir[ccom]=i; } for(i=1;i<=n;i++)if(!st[i])newcom(i); for(i=2;i<=n;i++)Log[i]=Log[i>>1]+1; for(i=1;i<=n;i++){ rmq[i].resize(i+1); for(j=1;j<=i;j++)rmq[i][j].init(); } for(i=ce;i;i--)if(!e[i].ban){ int x=st[e[i].x],y=st[e[i].y],val=e[i].v; for(int _=0;_<2;_++){ for(int r=x;r<=n;r++)for(int l=x;l;l--){ auto&f=rmq[r][l].f[0][y][val]; if(!f[0])f[0]=i; else if(f[0]!=i&&!f[1])f[1]=i; else break; } swap(x,y); } } for(i=1;i<=n;i++)for(j=1;j<=i;j++)rmq[i][j].build(); search(0,1); for(i=0;i<4;i++){ if(!opt[i])opt[i]=-1; printf("%d\n",opt[i]); } }