The 2023 ICPC Asia Hong Kong Regional Programming Contest (The 1st Universal Cup, Stage 2: Hong Kong)
题解:
https://files.cnblogs.com/files/clrs97/2022Hong_Kong_Tutorial.pdf
Code:
A. TreeScript
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; for (cin >> t; t; t -= 1) { int n; cin >> n; vector<int> p(n + 1); vector<vector<int>> g(n + 1); vector<int> dp(n + 1); for (int i = 1; i <= n; i += 1) cin >> p[i]; for (int i = n; i >= 1; i -= 1) { if (g[i].empty()) dp[i] = 1; else if (g[i].size() == 1) dp[i] = g[i][0]; else { sort(g[i].begin(), g[i].end(), greater<int>()); dp[i] = max(g[i][0], g[i][1] + 1); } g[p[i]].push_back(dp[i]); } cout << dp[1] << "\n"; } return 0; }
B. Big Picture
#include<bits/stdc++.h> using namespace std; typedef long long LL; const LL mod=998244353; const LL N=1200; LL a[N][N],b[N][N],n,m,e1[N][N]; void upd(LL &x,LL y){x=(x+y)%mod;} int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>m; for (LL i=1;i<=n;++i){ for (LL j=1;j<=m;++j){ cin>>a[i][j]; upd(a[i][j],a[i][j-1]); } } for (LL i=1;i<=n;++i){ for (LL j=1;j<=m;++j){ cin>>b[i][j]; upd(b[i][j],b[i-1][j]); } } LL E=0,V=0,S=0; // E: [out edge] // V: [node] // S: [inside edge] - [fake face] auto pr=[&](LL i,LL j)->LL { if (i==0||j==0) return 1; return 1-a[i][j-1]*b[i-1][j]%mod; }; for (LL i=1;i<=n;++i){ for (LL j=1;j<=m;++j){ upd(V,pr(i,j)); // cerr<<i<<' '<<j<<' '<<pr(i,j)<<'\n'; } } for (LL i=1;i<=n;++i){ for (LL j=1;j<=m;++j){ if (j>1){// edge([i,j-1],[i,j]) LL p=0; upd(p,1-pr(i,j-1)); upd(p,1-pr(i,j)); upd(p,-(a[i][j-2]*b[i-1][j-1]%mod*b[i-1][j])); upd(E,1-p); e1[i][j]=1-p; } if (i>1){// edge([i-1,j],[i,j]) LL p=0; upd(p,1-pr(i-1,j)); upd(p,1-pr(i,j)); upd(p,-(b[i-2][j]*a[i-1][j-1]%mod*a[i][j-1])); upd(E,1-p); } } } for (LL i=2;i<=n;++i){ for (LL j=2;j<=m;++j){ {//square LL p1=(1-a[i][j-1])*e1[i-1][j]%mod; LL p2=(a[i][j-1]-a[i][j-2])*(1-b[i-1][j])%mod*pr(i-1,j-1)%mod; LL p3=a[i][j-2]*(1-b[i-1][j])%mod*(1-b[i-1][j-1])%mod; upd(S,-(p1+p2+p3)); } {//diag LL p=a[i-1][j-2]*b[i-2][j-1]%mod*(a[i][j-1]-a[i][j-2])%mod*(b[i-1][j]-b[i-2][j])%mod; upd(S,p); } } } // cerr<<E<<' '<<V<<' '<<S<<'\n'; LL ans=(1+1+1+E-V+S)%mod; cout<<(ans+mod)%mod<<'\n'; }
C. Painting Grid
#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; int ok=1; if(m<=10 and (1<<m)<n)ok=0; if(n<=10 and (1<<n)<m)ok=0; if(not ok or n*m%2==1)cout<<"NO\n"; else { cout<<"YES\n"; int sw=0; if(m%2!=0)sw=1,swap(n,m); vector<vector<int>> ans(n+5,vector<int>(m+5)); int mx; for(int i=1;i<=m/2;i++)ans[1][i]=1,mx=1; set<vector<int>> s; vector<vector<int>> tmp; { auto rev=ans[1]; for(int i=1;i<=m;i++)rev[i]^=1; tmp.push_back(rev); s.insert(rev);s.insert(ans[1]); } for(int b=0;(1<<b)<m/2;b++) { // cerr<<"go "<<b<<endl; for(int i=0;i<m/2;i++) { ans[b+2][i+1]=(i>>b)&1; ans[b+2][i+m/2+1]=((i>>b)&1)^1; } auto rev=ans[b+2]; for(int i=1;i<=m;i++)rev[i]^=1; tmp.push_back(rev); s.insert(rev);s.insert(ans[b+2]); mx=max(mx,b+2); } vector<int> now(m+5); // auto chk=[&](){int ret=0;for(int i=1;i<=m;i++)ret+=now[i];return ret;}; auto nxt=[&](){for(int i=m;i>=1;i--)if(now[i]==1)now[i]=0;else {now[i]=1;return true;}return false;}; mx++; while(mx+1<=n) { if(s.count(now)) { if(nxt()) continue; else break; } auto rnow=now; for(int i=1;i<=m;i++)rnow[i]^=1; ans[mx]=now; ans[mx+1]=rnow; s.insert(now); s.insert(rnow); mx+=2; nxt(); } while(mx<=n) { ans[mx]=tmp.back(); tmp.pop_back(); mx++; } if(sw) { for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) cout<<ans[j][i]; cout<<"\n"; } } else { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) cout<<ans[i][j]; cout<<"\n"; } } } } return 0; }
D. Shortest Path Query
#include<cstdio> #include<vector> #include<algorithm> using namespace std; const int N=50005,Q=50005,MASK=1023,inf=~0U>>1; int n,m,q,cnt,i,j,k,x,y,z,e[Q][2],ans[Q]; vector<int>g[N][2],h[N]; struct P{int x,y;P(){}P(int _x,int _y){x=_x,y=_y;}}hull[N*2]; vector<P>f[MASK+2],cur; inline void up(int&a,int b){a>b?(a=b):0;} inline void ext(const P&p,int dx,int dy){ if(cnt){ if(hull[cnt].y<=p.y+dy)return; if(hull[cnt].x==p.x+dx)cnt--; } while(cnt>1&&1LL*(hull[cnt].y-hull[cnt-1].y)*(p.x+dx-hull[cnt].x)>=1LL*(p.y+dy-hull[cnt].y)*(hull[cnt].x-hull[cnt-1].x))cnt--; hull[++cnt]=P(p.x+dx,p.y+dy); } inline void merge(const vector<P>&v,int dx,int dy){ cnt=0; int i=0,j=0; while(i<cur.size()&&j<v.size()){ if(cur[i].x<v[j].x+dx)ext(cur[i++],0,0); else ext(v[j++],dx,dy); } while(i<cur.size())ext(cur[i++],0,0); while(j<v.size())ext(v[j++],dx,dy); cur.resize(cnt); for(i=0;i<cnt;i++)cur[i]=hull[i+1]; } int main(){ scanf("%d%d",&n,&m); while(m--){ scanf("%d%d%d",&x,&y,&z); g[y][z].push_back(x); } scanf("%d",&q); for(i=1;i<=q;i++){ scanf("%d%d%d",&x,&y,&z); e[i][0]=x; e[i][1]=y; h[z].push_back(i); } for(i=1;i<=n;i++){ cur.clear(); if(i==1)cur.push_back(P(0,0)); for(j=0;j<g[i][0].size();j++)merge(f[g[i][0][j]&MASK],1,0); for(j=0;j<g[i][1].size();j++)merge(f[g[i][1][j]&MASK],0,1); for(j=0;j<h[i].size();j++){ z=h[i][j]; x=e[z][0]; y=e[z][1]; int tmp=inf; for(k=0;k<cur.size();k++)up(tmp,x*cur[k].x+y*cur[k].y); ans[z]=tmp; } swap(cur,f[i&MASK]); } for(i=1;i<=q;i++)printf("%d\n",ans[i]); }
E. Goose, Goose, DUCK?
#include<bits/stdc++.h> using namespace std; const int N=1e6+1e3+7,L=1e6; int n,k,a[N]; vector<int>pos[N]; struct T{ int l,r,ls,rs; int mx,cnt; int tag; }t[N*2+1]; int cnt; void add(int x,int v) { t[x].tag+=v; t[x].mx+=v; } void pushdown(int x) { if(t[x].tag) { add(t[x].ls,t[x].tag); add(t[x].rs,t[x].tag); t[x].tag=0; } } void update(int x) { t[x].mx=max(t[t[x].ls].mx,t[t[x].rs].mx); t[x].cnt=(t[x].mx==t[t[x].ls].mx)*t[t[x].ls].cnt+(t[x].mx==t[t[x].rs].mx)*t[t[x].rs].cnt; } int build(int l,int r) { int x=++cnt; t[x].l=l,t[x].r=r; if(l==r) { t[x].cnt=1; return x; } int mid=(l+r)>>1; t[x].ls=build(l,mid); t[x].rs=build(mid+1,r); update(x); return x; } void change(int x,int l,int r,int v) { if(l<=t[x].l&&t[x].r<=r) { add(x,v); return; } pushdown(x); int mid=(t[x].l+t[x].r)>>1; if(l<=mid) change(t[x].ls,l,r,v); if(r>mid) change(t[x].rs,l,r,v); update(x); } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>k; for(int i=1;i<=n;i++) cin>>a[i]; long long ans=0; build(1,n); for(int i=1;i<=n;i++) { change(1,i,i,L); if(pos[a[i]].size()>=k) { int r=pos[a[i]][pos[a[i]].size()-k],l=pos[a[i]].size()==k?1:pos[a[i]][pos[a[i]].size()-k-1]+1; change(1,l,r,1); } pos[a[i]].push_back(i); if(pos[a[i]].size()>=k) { int r=pos[a[i]][pos[a[i]].size()-k],l=pos[a[i]].size()==k?1:pos[a[i]][pos[a[i]].size()-k-1]+1; change(1,l,r,-1); } if(t[1].mx==L) ans+=t[1].cnt; } cout<<ans<<"\n"; }
F. Sum of Numbers
#include <bits/stdc++.h> using namespace std; constexpr int base = 10; struct Dec{ vector<int> d; Dec(vector<int> d = {0}): d(d) { assert(not d.empty()); } bool is_zero() const { return d.size() == 1 and d[0] == 0; } Dec& operator += (const Dec& dec) { int carry = 0; int msize = max(d.size(), dec.d.size()); d.resize(msize); for (int i = 0; i < msize; i += 1) { if (i < dec.d.size()) d[i] += dec.d[i]; d[i] += carry; if (d[i] >= base) { carry = 1; d[i] -= base; } else { carry = 0; } } if (carry) d.push_back(carry); return *this; } bool operator < (const Dec& dec) const { if (d.size() != dec.d.size()) return d.size() < dec.d.size(); for (int i = d.size() - 1; i >= 0; i -= 1) if (d[i] != dec.d[i]) return d[i] < dec.d[i]; return false; } }; ostream& operator << (ostream& out, const Dec& dec) { for (int i = dec.d.size() - 1; i >= 0; i -= 1) out << dec.d[i]; return out; }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; map<int, map<int, vector<vector<int>>>> mp; for (cin >> t; t; t -= 1) { int n, k; string sr; cin >> n >> k >> sr; vector<int> p(n); for (int i = 0; i < n; i += 1) { p[i] = sr[n - i - 1] - '0'; } auto f = [&](int L, int R) -> Dec { return Dec(vector<int>(p.begin() + (n - 1 - R), p.begin() + (n - L))); }; if (not mp.count(k)) { vector<int> a(k); function<void(int)> DFS = [&](int u) { if (u == k) { vector<int> s(k); for (int i = 0; i < k; i += 1) { if (i) s[i] = s[i - 1]; s[i] += a[i]; } int ss = 0; for (int si : s) ss += si; mp[k][(ss % (k + 1) + k + 1) % (k + 1)].push_back(s); return; } for (int i : {0, -1, 1}) { a[u] = i; DFS(u + 1); } }; DFS(0); } Dec ans; for (auto s : mp[k][n % (k + 1)]) { int ss = 0; for (int si : s) ss += si; int x = (n - ss) / (k + 1); int ok = x > 0; for (int si : s) ok &= x + si > 0; if (not ok) continue; Dec pans = f(0, x - 1); int L = x; for (int si : s) { si += x; if (not ans.is_zero() and si > ans.d.size()) { ok = 0; break; } pans += f(L, L + si - 1); if (not ans.is_zero() and ans < pans) { ok = 0; break; } L += si; } if (not ok) continue; if (ans.is_zero() or pans < ans) ans = pans; } cout << ans << "\n"; } return 0; }
G. Paddle Star
#include<bits/stdc++.h> using namespace std; const double pi=acos(-1); int T; double l1,l2,alp,bet; double trans(double deg) { return deg/180*pi; } double fix(double x) { return min(max(x,-1.0),1.0); } int main() { int Case=0; scanf("%d",&T); while(T--) { scanf("%lf%lf%lf%lf",&l1,&l2,&alp,&bet); alp=trans(alp); bet=trans(bet); double ans=(l1+l2)*(l1+l2)*alp+l2*l2*bet; if(bet<=pi/2) { printf("%.15lf\n",ans); continue; } else { double rc=pi-bet; double A=l1,B=l2; double C=sqrt(max(A*A+B*B-2*A*B*cos(rc),0.0)); double rb=asin(fix(B*sin(rc)/C)); double ra=pi-rb-rc; if(ra>=pi/2) { double t=min(rb,alp*2); double S=0.5*A*B*sin(rc); double rcc=pi-ra-(rb-t); double AA=C/sin(rcc)*sin(ra); S-=0.5*C*AA*sin(rb-t); S-=C*C*t*0.5; ans+=S*2; } else { double S=0.5*A*B*sin(rc); double H=S*2/B; double rL=acos(fix(H/C)); S-=0.5*C*H*sin(rL); double rR=rb-rL; double t=min(rR,alp*2); S-=H*H*t*0.5; S-=0.5*H*H*tan(rR-t); ans+=S*2; } printf("%.15lf\n",ans); } } }
H. Another Goose Goose Duck Problem
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define data dataa #define rep(i,n) for(int i=1;i<=n;i++) typedef long long LL; int main() { int l,r,b,k; scanf("%d%d%d%d",&l,&r,&b,&k); printf("%lld\n",(LL)((l-1)/b+1)*b*k); return 0; }
I. Range Closest Pair of Points Query
#include<cstdio> #include<vector> using namespace std; typedef unsigned int U; typedef long long ll; const int N=250005,Q=250005,BLK=9,M=(N>>BLK)+5,K=28,Base=(1<<21)-1; const ll inf=1LL<<60; int n,m,i,j,x,y,g[N],v[Q],nxt[Q]; int cb;ll val[N],mi[M],ans[Q]; struct P{int x,y;}a[N]; inline ll dis(const P&a,const P&b){return 1LL*(a.x-b.x)*(a.x-b.x)+1LL*(a.y-b.y)*(a.y-b.y);} inline void up(ll&a,ll b){a>b?(a=b):0;} inline void modify(int x,ll p){up(val[x],p);up(mi[x>>BLK],p);} inline ll query(int x){ ll ret=inf; int X=x>>BLK; for(int i=x;(i>>BLK)==X&&i<=n;i++)up(ret,val[i]); for(int i=X+1;i<=cb;i++)up(ret,mi[i]); return ret; } struct Layer{ int g[Base+2],vx[N],vy[N],nxt[N],ed; int rad; vector<int>pool[N]; int st[N],size[N]; int head; int ask(int x,int y){ if(x<0||y<0)return 0; U val=((((U)x)<<8)^y)&Base; for(int i=g[val];i;i=nxt[i])if(vx[i]==x&&vy[i]==y)return i; return 0; } int ins(int x,int y){ U val=((((U)x)<<8)^y)&Base; for(int i=g[val];i;i=nxt[i])if(vx[i]==x&&vy[i]==y)return i; vx[++ed]=x; vy[ed]=y; nxt[ed]=g[val]; g[val]=ed; return ed; } void insert(int o){pool[ins(a[o].x>>rad,a[o].y>>rad)].push_back(o);} void init(){ for(int i=1;i<=ed;i++)st[i]=pool[i].size()-1; head=1; } void search(int o){ int A=a[o].x>>rad,B=a[o].y>>rad; for(int X=A-1;X<=A+1;X++)for(int Y=B-1;Y<=B+1;Y++){ int O=ask(X,Y); if(!O)continue; int i=st[O]; while(i>=0&&pool[O][i]<head)i--; for(st[O]=i;i>=0;i--){ int who=pool[O][i]; if(who>=o)break; ll now=dis(a[o],a[who]); if(now>>(rad*2))continue; if(!(now>>((rad-1)*2))){ if(head<=who)head=who+1; continue; } modify(who,now); } } } }layer[K]; int main(){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y); for(i=1;i<=m;i++){ scanf("%d%d",&x,&y); v[i]=x; nxt[i]=g[y]; g[y]=i; } cb=n>>BLK; for(i=0;i<=cb;i++)mi[i]=inf; for(i=1;i<=n;i++)val[i]=inf; for(i=0;i<K;i++)layer[i].rad=i+1; for(i=n;i;i--)for(j=0;j<K;j++)layer[j].insert(i); for(i=0;i<K;i++)layer[i].init(); for(i=1;i<=n;i++){ for(j=0;j<K;j++){ if(j&&layer[j-1].head>layer[j].head)layer[j].head=layer[j-1].head; layer[j].search(i); } for(j=g[i];j;j=nxt[j]){ x=v[j]; if(x<layer[0].head)ans[j]=0;else ans[j]=query(x); } } for(i=1;i<=m;i++)printf("%lld\n",ans[i]); }
J. Dice Game
#include<bits/stdc++.h> using namespace std; #define int long long const int P=998244353; typedef pair<int,int> pii; #define fs first #define sd second #define mp make_pair int qpow(int a,int b) { int ret=1; while(b) { if(b&1) ret=ret*a%P; b>>=1; a=a*a%P; } return ret; } int n; int val[31],L,R; pii operator +(const pii &a,const pii &b) { return {max(a.fs,b.fs),min(a.sd,b.sd)}; } pii f[2][2][31]; int vis[2][2][31]; pii dp(int p,int up,int dw) { if(p==-1) return mp(0,0); if(vis[up][dw][p]) return f[up][dw][p]; vis[up][dw][p]=1; pii ret(-1e18,1e18); for(int i=dw?L>>p&1:0;i<=(up?R>>p&1:1);i++) { auto nxt=dp(p-1,up&&i==(R>>p&1),dw&&i==(L>>p&1)); nxt.first+=(i?-val[p]:val[p]); nxt.second+=(i?-val[p]:val[p]); ret=ret+nxt; } return f[up][dw][p]=ret; } int c1(int N,int i) { return N/(1<<i+1)*(1<<i)+max(0ll,N%(1<<i+1)-(1<<i)); } pii getv(int l,int r) { memset(vis,0,sizeof(vis)); L=l,R=r; return dp(30,1,1); } int sgn(int x) { return x>=0?1:-1; } int ans=0,ivn; void solve(int l,int r) { pii res=getv(l,r); if(sgn(res.fs)==sgn(res.sd)) { if(sgn(res.fs)>=0) { int sum=0; for(int i=30;i>=0;i--) { int x1=val[i]/(1<<i),x0=(n-x1),y1=c1(r+1,i)-c1(l,i),y0=r-l+1-y1; sum=(sum+(x1*y0%P+x0*y1%P)*(1<<i))%P; } ans=(ans+sum*ivn)%P; } else ans=(ans+(l+r)*(r-l+1)/2)%P; return; } int mid=(l+r)>>1; solve(l,mid); solve(mid+1,r); } signed main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin>>T; while(T--) { cin>>n; ivn=qpow(n,P-2); for(int i=0;i<=30;i++) val[i]=c1(n,i)*(1<<i); ans=0; solve(0,n-1); ans=ans*ivn%P; cout<<ans<<"\n"; } }
K. Maximum GCD
#include<bits/stdc++.h> using namespace std; const int N=1e6+1e3+7; set<int>s; int n; int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n; for(int i=1;i<=n;i++) { int x; cin>>x; s.insert(x); } int ans=s.size()==1?*s.begin():(*s.begin())/2; if(s.size()>1) { if((*next(s.begin()))/2>=*s.begin()) ans=*s.begin(); } cout<<ans<<endl; }
L. Permutation Compression
#include<bits/stdc++.h> using namespace std; const int N=2e5+1e3+7; int T,n,m,k,p[N],q[N],l[N],pos[N],del[N]; int c[N]; void add(int x,int v) { while(x<=n) { c[x]+=v; x+=x&-x; } } int qry(int x) { int ret=0; while(x) { ret+=c[x]; x-=x&-x; } return ret; } int main() { scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) scanf("%d",&p[i]),pos[p[i]]=i,del[i]=1,c[i]=0; for(int i=1;i<=m;i++) scanf("%d",&q[i]),del[q[i]]=0; for(int i=1;i<=k;i++) scanf("%d",&l[i]); bool ok=1; for(int i=1;i<m;i++) if(pos[q[i]]>pos[q[i+1]]) ok=0; if(!ok) { puts("NO"); continue; } set<int>s; vector<int>nd; for(int i=n;i>=1;i--) { int x=pos[i]; if(!del[i]) s.insert(x); else { auto it=s.lower_bound(x); int r=it==s.end()?n:*it-1; int l=it==s.begin()?1:*prev(it)+1; nd.push_back((r-l+1)-(qry(r)-qry(l-1))); add(x,1); } } sort(nd.begin(),nd.end()); sort(l+1,l+k+1); int p=k; while(nd.size()) { int x=nd.back(); nd.pop_back(); while(p>0&&l[p]>x) p--; if(!p) { ok=0; break; } p--; } puts(ok?"YES":"NO"); } }