The 2023 ICPC Asia Hangzhou Regional Contest (The 2nd Universal Cup. Stage 22: Hangzhou)
题解:
https://files.cnblogs.com/files/clrs97/2023hangzhou_tutorials-2-22.pdf
Code:
A. Submissions
#include <bits/stdc++.h> using namespace std; using Submission = tuple<string, char, int, string>; using Score = pair<int, int>; Score operator+(const Score &s0, const Score &s1) { return Score(s0.first + s1.first, s0.second + s1.second); } Score operator-(const Score &s0, const Score &s1) { return Score(s0.first - s1.first, s0.second - s1.second); } int main() { cin.tie(nullptr)->sync_with_stdio(false); int T; cin >> T; for (int ti = 0; ti < T; ti += 1) { int n = 0, m; cin >> m; vector<Submission> submissions(m); unordered_map<string, int> mp; vector<string> names; vector<array<vector<pair<int, bool>>, 26>> tp; for (auto &[c, p, t, s] : submissions) { cin >> c >> p >> t >> s; if (not mp.count(c)) { mp[c] = n++; names.push_back(c); tp.emplace_back(); } tp[mp[c]][p - 'A'].emplace_back(t, s == "accepted"); } auto print = [&](string s) { cout << count(s.begin(), s.end(), '1') << "\n"; for (int i = 0; i < n; i += 1) { if (s[i] == '1') { cout << names[i] << " "; } } cout << "\n"; }; auto score = [&](const vector<pair<int, bool>> &vp) -> Score { int p = 0; for (auto [t, s] : vp) { if (s) { return Score(1, -t - p); } p += 20; } return Score(0, 0); }; vector<Score> s(n), bs(n), ws(n); for (int i = 0; i < n; i += 1) { for (int j = 0; j < 26; j += 1) { s[i] = s[i] + score(tp[i][j]); } bs[i] = ws[i] = s[i]; for (int j = 0; j < 26; j += 1) { auto vp = tp[i][j]; if (not vp.empty()) { vp[0].second = true; } bs[i] = max(bs[i], s[i] - score(tp[i][j]) + score(vp)); } for (int j = 0; j < 26; j += 1) { auto vp = tp[i][j]; for (auto &[t, s] : vp) { if (s) { s = false; break; } } ws[i] = min(ws[i], s[i] - score(tp[i][j]) + score(vp)); } } int k = n - count(s.begin(), s.end(), Score(0, 0)); int r = min((k + 9) / 10, 35); auto ss = s; sort(ss.begin(), ss.end()); string ans(n, '0'); if (k == 0) { ss.emplace_back(1, numeric_limits<int>::min()); } for (int i = 0; i < n; i += 1) { if (bs[i] >= ss[n - r]) { ans[i] = '1'; } if (bs[i].first and not s[i].first and min(k / 10 + 1, 35) > r and bs[i] >= ss[n - r - 1]) { ans[i] = '1'; } } if (r == n or ss[n - r - 1] == ss[n - r]) { print(ans); continue; } int ok = 0; for (int i = 0; i < n; i += 1) { if (s[i] >= ss[n - r]) { if (ws[i] <= ss[n - r - 1]) { if (ws[i].first or min((k + 8) / 10, 35) == r) { ok = 1; } } } if (s[i].first == 0) { int m = -1; for (auto &p : tp[i]) { if (not p.empty()) { m = max(m, p.back().first + ((int)p.size() - 1) * 20); } } if (m != -1 and Score(1, -m) <= ss[n - r - 1] and min(k / 10 + 1, 35) > r) { ok = 1; } } } if (ok) { for (int i = 0; i < n; i += 1) { if (s[i] == ss[n - r - 1]) { ans[i] = '1'; } } } print(ans); } }
B. Festival Decorating
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; typedef double ld; const int N=550001,LIM=1028; const ld pi=acosl(-1.0); int n,q,mx,i,j,k,x,c,loc[N],col[N],val[N],l,r,ans[N],pos[N]; struct comp{ ld r,i;comp(ld _r=0,ld _i=0){r=_r,i=_i;} void clear(){r=i=0;} comp operator+(const comp&x)const{return comp(r+x.r,i+x.i);} comp operator-(const comp&x)const{return comp(r-x.r,i-x.i);} comp operator*(const comp&x)const{return comp(r*x.r-i*x.i,r*x.i+i*x.r);} }A0[N],A1[N],A2[N],B0[N],B1[N],B2[N],F[N],w[N],ww[N]; inline void FFT(comp a[],int n,int o){ for(int i=1;i<n;i++)if(i<pos[i])swap(a[i],a[pos[i]]); for(int d=0,k=__builtin_ctz(n);(1<<d)<n;d++){ int m=1<<d,m2=m<<1; for(int i=0;i<n;i+=m2)for(int j=0;j<m;j++){ comp&A=a[i+j+m],&B=a[i+j],t=(o==1?w[j<<(k-d)]:ww[j<<(k-d)])*A; A=B-t;B=B+t; } } if(o==-1)for(int i=0;i<n;i++)a[i].r/=n; } inline void solve(int x,int l,int r){ for(;l<=r;l++)if(val[loc[l]+x]&&col[l]!=val[loc[l]+x]){ ans[x]=l; break; } } int main(){ scanf("%d%d",&n,&q); for(i=1;i<=n;i++){ scanf("%d%d",&loc[i],&col[i]); val[loc[i]]=col[i]; if(loc[i]>mx)mx=loc[i]; } for(k=1;k<mx*2;k<<=1); j=__builtin_ctz(k)-1; for(i=0;i<k;i++)pos[i]=pos[i>>1]>>1|((i&1)<<j); for(i=0;i<k;i++)w[i]=comp(cosl(pi*i/k),sinl(pi*i/k)); for(i=0;i<k;i++)ww[i]=w[i],ww[i].i*=-1; for(i=1;i<=n;i++){ x=loc[i],c=col[i]; B0[x].r=1; B1[x].r=-2*c; B2[x].r=((ld)c)*((ld)c); } FFT(B0,k,1); FFT(B1,k,1); FFT(B2,k,1); l=min(n,LIM); for(i=1;i<mx;i++)solve(i,1,l); l++; while(l<=n){ r=l*3; if(r&1)r--; r=min(r,n); for(i=0;i<k;i++){ A0[i].clear(); A1[i].clear(); A2[i].clear(); } for(i=l;i<=r;i++){ x=mx-loc[i],c=col[i]; A0[x].r=((ld)c)*((ld)c); A1[x].r=c; A2[x].r=1; } FFT(A0,k,1); FFT(A1,k,1); FFT(A2,k,1); for(i=0;i<k;i++)F[i]=A0[i]*B0[i]+A1[i]*B1[i]+A2[i]*B2[i]; FFT(F,k,-1); for(i=1;i<mx;i++){ if(ans[i])continue; if(F[mx+i].r>0.5)ans[i]=r/2; } l=r+1; } while(q--)scanf("%d",&x),printf("%d\n",ans[x]); } /* [l,3l] 1.5l */
C. Yet Another Shortest Path Query
#include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef pair<int,int>P; const int BUF=50000000; char Buf[BUF],*buf=Buf; inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} const int OUT=13000000; char Out[OUT],*ou=Out;int Outn[15],Outcnt; inline void write(int x){ if(x==-1){ *ou++='-'; *ou++='1'; return; } if(!x)*ou++=48; else{ for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48; while(Outcnt)*ou++=Outn[Outcnt--]; } } inline void writeln(int x){write(x);*ou++='\n';} const int N=1000005,M=N*3,Q=1000005,inf=500000000; int n,m,cq,i,x,y,z,ans[Q],e[M][3],deg[N],g[N],v[M<<1],nxt[M<<1],ed; int q[N],h,t,ord[N];bool vis[N]; vector<P>ga[N],gr[N]; inline void add(int x,int y){deg[x]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} inline void ext(int x){if(deg[x]<=5&&!vis[x])vis[q[++t]=x]=1;} inline void up(int&a,int b){a>b?(a=b):0;} struct E{int o,x,y,z;E(){}E(int _o,int _x,int _y,int _z){o=_o,x=_x,y=_y,z=_z;}}; int cur,val[N],last[N]; inline void update(int x,int y){if(last[x]!=cur)last[x]=cur,val[x]=y;else up(val[x],y);} namespace TWO{ const int MAXQ=Q*20; int ce,cnt[N],pool[MAXQ];E e[MAXQ]; inline void solve(int o,int x,int y,int z){ if(x==y){up(ans[o],z);return;} e[++ce]=E(o,x,y,z); cnt[x]++; e[++ce]=E(o,y,x,z); cnt[y]++; } inline void single(int x){ if(x==cur)return; cur=x; for(const auto&A:ga[x]){ update(A.first,A.second); for(const auto&B:gr[A.first])update(B.first,A.second+B.second); } } void run(){ int i,u; for(i=1;i<=n;i++)cnt[i]+=cnt[i-1]; for(i=1;i<=ce;i++)pool[cnt[e[i].x]--]=i; for(cur=0,i=1;i<=n;i++)last[i]=0; for(i=1;i<=ce;i++){ u=pool[i]; single(e[u].x); if(last[e[u].y]==cur)up(ans[e[u].o],val[e[u].y]+e[u].z); } } } namespace THREE{ const int MAXQ=Q*2; int ce,cnt[N],pool[MAXQ];E e[MAXQ]; inline void solve(int o,int x,int y){ for(const auto&A:gr[x])TWO::solve(o,y,A.first,A.second); for(const auto&A:gr[y])TWO::solve(o,x,A.first,A.second); e[++ce]=E(o,x,y,0); cnt[x]++; e[++ce]=E(o,y,x,0); cnt[y]++; } inline void single(int x){ if(x==cur)return; cur=x; for(const auto&A:ga[x])for(const auto&B:gr[A.first]){ int w=A.second+B.second; update(B.first,w); for(const auto&C:gr[B.first])update(C.first,w+C.second); } } void run(){ int i,u; for(i=1;i<=n;i++)cnt[i]+=cnt[i-1]; for(i=1;i<=ce;i++)pool[cnt[e[i].x]--]=i; for(cur=0,i=1;i<=n;i++)last[i]=0; for(i=1;i<=ce;i++){ u=pool[i]; single(e[u].x); if(last[e[u].y]==cur)up(ans[e[u].o],val[e[u].y]); } } } int main(){ fread(Buf,1,BUF,stdin);read(n);read(m); for(i=1;i<=m;i++){ read(x);read(y);read(z); e[i][0]=x,e[i][1]=y,e[i][2]=z; add(x,y),add(y,x); } for(h=i=1;i<=n;i++){ ext(i); ga[i].reserve(deg[i]); gr[i].reserve(5); } while(h<=t)for(i=g[x=q[h++]];i;i=nxt[i]){ y=v[i]; if(vis[y])continue; deg[y]--; ext(y); } for(i=1;i<=n;i++)ord[q[i]]=i; for(i=1;i<=m;i++){ x=e[i][0],y=e[i][1],z=e[i][2]; if(ord[x]>ord[y])swap(x,y); gr[x].emplace_back(P(y,z)); ga[x].emplace_back(P(y,z)); ga[y].emplace_back(P(x,z)); } read(cq); for(i=1;i<=cq;i++){ read(x);read(y); ans[i]=inf; THREE::solve(i,x,y); } TWO::run(); THREE::run(); for(i=1;i<=cq;i++){ x=ans[i]; if(x==inf)x=-1; writeln(x); } fwrite(Out,1,ou-Out,stdout); }
D. Operator Precedence
#include "bits/stdc++.h" using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); int T; cin>>T; while (T--) { int n,i; cin>>n; cout<<2*n-3; for (i=1; i<n; i++) cout<<" 2 -1"; cout<<" 1\n"; } }
E. Period of a String
#include<bits/stdc++.h> using namespace std; int n ; string s[100005]; struct my_list { int num[26] , id; my_list() { memset(num,0,sizeof(num)) ; } }p[100005]; int L[100005]; bool operator < (const my_list &A,const my_list &B) { return A.id < B.id; } void solv() { cin >> n; for(int i = 1;i <= n;i++) { cin >> s[i] ; memset(p[i].num,0,sizeof(p[i].num)) ; L[i] = s[i].size() ; for(int j = 0;j < s[i].size();j++) { p[i].num[s[i][j] - 'a']++; } p[i].id = i; } set<pair<int,my_list> > st; bool ok = 1; for(int i = n;i >= 1 && ok;i--) { while(st.size() && (--st.end())->first >= L[i] && ok) { auto it = st.end() ; it-- ; int len = it->first ; my_list k = it->second ; st.erase(it) ; int pr = len / L[i] ; len %= L[i] ; for(int j = 0;j < 26;j++) { if(k.num[j] < 1LL * p[i].num[j] * pr) {ok = 0 ; break ;} ///有可能爆int,记得卡 k.num[j] -= p[i].num[j] * pr; } if(len) st.insert({len , k}) ; } st.insert({L[i] , p[i]}) ; } if(!ok) { cout << "NO\n" ; return ; } vector<pair<int,my_list> > v(st.begin() , st.end()) ; string s1 ; my_list cur ; for(int i = 0;i < v.size() && ok;i++) { // printf("%d : " , v[i].first) ; for(int j = 0;j < 26;j++) { // printf("%d ",v[i].second.num[j]) ; if(v[i].second.num[j] >= cur.num[j]) { for(int k = cur.num[j] + 1 ; k <= v[i].second.num[j] ; k++) s1 += (j + 'a') ; cur.num[j] = v[i].second.num[j] ; } else {ok = 0 ; break ;} } // printf("\n") ; } if(!ok) { cout << "NO\n" ; return ; } cout << "YES\n" ; for(int i = 1 ; i <= n;i++) { cout << s1 << '\n' ; if(i == n) break ; if(L[i + 1] < s1.size()) s1.resize(L[i + 1]) ; else { int d = s1.size() ; for(int j = s1.size() ; j < L[i + 1] ; j++) s1 += (s1[j % d]) ; } } return ; } int main() { //freopen("in.txt","r",stdin) ; ios::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ; int t;cin >> t; while(t--) solv() ; }
F. Top Cluster
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=500005,K=21; const int BUF=30000000; char Buf[BUF],*buf=Buf; inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} inline void readll(ll&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} const int OUT=7000000; char Out[OUT],*ou=Out;int Outn[15],Outcnt; inline void write(int x){ if(!x)*ou++=48; else{ for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48; while(Outcnt)*ou++=Outn[Outcnt--]; } } inline void writeln(ll x){write(x);*ou++='\n';} int n,m,mx,i,j,x,y,z,id[N]; int g[N],v[N<<1],w[N<<1],nxt[N<<1],ed,dfn,loc[N],Log[N<<1]; ll d[N],q[K][N<<1],k; inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;} void dfs(int x,int y){ q[0][loc[x]=++dfn]=d[x]; for(int i=g[x];i;i=nxt[i])if(v[i]!=y){ d[v[i]]=d[x]+w[i]; dfs(v[i],x); q[0][++dfn]=d[x]; } } inline ll lca(int x,int y){ x=loc[x],y=loc[y]; if(x>y)swap(x,y); int k=Log[y-x+1]; return min(q[k][x],q[k][y-(1<<k)+1]); } inline ll dis(int x,int y){return x==y?0:d[x]+d[y]-lca(x,y)*2;} struct P{ int a,b;ll d; P(){} P(int x){a=b=x,d=0;} void add(int x){ ll now=dis(x,a); int na=a,nb=b; if(now>d)d=now,na=a,nb=x; now=dis(x,b); if(now>d)d=now,na=b,nb=x; a=na,b=nb; } }dia[N]; inline int ask(int x,ll k){ int ret=mx+1,l=0,r=mx,mid; while(l<=r){ mid=(l+r)>>1; if(dis(x,dia[mid].a)>k||dis(x,dia[mid].b)>k)r=(ret=mid)-1;else l=mid+1; } return ret; } int main(){ fread(Buf,1,BUF,stdin); read(n);read(m); for(i=1;i<=n;i++){ read(x); if(x<n)id[x]=i; } for(i=1;i<n;i++){ read(x);read(y);read(z); add(x,y,z); add(y,x,z); } dfs(1,0); for(i=2;i<=dfn;i++)Log[i]=Log[i>>1]+1; for(i=1;i<K;i++)for(j=1;j+(1<<i)-1<=dfn;j++)q[i][j]=min(q[i-1][j],q[i-1][j+(1<<(i-1))]); for(i=0;i<n;i++){ x=id[i]; if(!x)break; if(!i)dia[i]=P(x); else{ dia[i]=dia[i-1]; dia[i].add(x); } mx=i; } while(m--){ read(x);readll(k); writeln(ask(x,k)); } fwrite(Out,1,ou-Out,stdout); }
G. Snake Move
#include<cstdio> typedef unsigned long long ull; const int N=3005,K=100005,inf=~0U>>1; int n,m,k,i,j,x,y,sx,sy; int pos[K][2],lim[N][N],f[N][N],h,t,q[N*N][2]; char a[N][N]; inline void ext(int x,int y,int z){ if(x<1||x>n||y<1||y>m)return; if(a[x][y]=='#')return; if(z<lim[x][y]){ z=lim[x][y]; if(z<f[x][y])f[x][y]=z; return; } if(z>=f[x][y])return; f[x][y]=z; q[++t][0]=x; q[t][1]=y; } inline void branch(int x,int y,int z){ if(f[x][y]!=z)return; z++; ext(x-1,y,z); ext(x+1,y,z); ext(x,y-1,z); ext(x,y+1,z); } int main(){ scanf("%d%d%d",&n,&m,&k); scanf("%d%d",&sx,&sy); for(i=k-1;i;i--){ scanf("%d%d",&x,&y); lim[x][y]=i; pos[i][0]=x; pos[i][1]=y; } for(i=1;i<=n;i++)scanf("%s",a[i]+1); for(i=1;i<=n;i++)for(j=1;j<=m;j++)f[i][j]=inf; ext(sx,sy,0); i=1; while(1){ int f1=inf; if(h<=t){ x=q[h][0]; y=q[h][1]; f1=f[x][y]; } int f2=i<k?i:inf; if(f1==inf&&f2==inf)break; if(f1<f2){ branch(x,y,f1); h++; }else{ branch(pos[i][0],pos[i][1],i); i++; } } ull ans=0; for(i=1;i<=n;i++)for(j=1;j<=m;j++){ ull tmp=f[i][j]; //printf("%d%c",f[i][j]==inf?-1:f[i][j],j<m?' ':'\n'); if(tmp==inf)continue; ans+=tmp*tmp; } printf("%llu",ans); }
H. Sugar Sweet II
#include <bits/stdc++.h> using namespace std; int n; int a[500005] , b[500005] , w[500005]; vector<int> E[500005]; int len[500005]; int st[500005]; bool vis[500005]; void dfs(int u , int d) { vis[u] = 1; len[u] = d; for(auto v : E[u]) { if(!vis[v] && st[v] == 1) dfs(v , d + 1) ; } } int t[500005]; const int mod = 1e9 + 7; int fpow(int a,int b) { int ans = 1; while(b) { if(b & 1) ans = 1LL * ans * a % mod; a = 1LL*a*a%mod;b >>= 1; } return ans; } void solv() { cin >> n; for(int i = 1;i <= n;i++) E[i].clear() , len[i] = vis[i] = 0; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= n;i++) { cin >> b[i]; E[b[i]].push_back(i) ; } for(int i = 1;i <= n;i++) cin >> w[i]; for(int i = 1;i <= n;i++) { if(i == b[i] || a[i] >= a[b[i]] + w[b[i]]) st[i] = 0 ; ///不会发生 else if(a[i] >= a[b[i]] && a[i] < a[b[i]] + w[b[i]]) st[i] = 1 ; ///只有父亲发生了才能发生 else st[i] = 2 ; ///一定发生 } for(int i = 1;i <= n;i++) { if(st[i] == 2) dfs(i , 1) ; } t[0] = 1; t[1] = 1; for(int i = 2;i <= n;i++) t[i] = 1LL * (mod - mod / i) * t[mod % i] % mod; for(int i = 1;i <= n;i++) t[i] = 1LL * t[i] * t[i - 1] % mod; for(int i = 1;i <= n;i++) { if(len[i]) cout << (a[i] + 1LL * t[len[i]] * w[i]) % mod <<' '; else cout << a[i] <<' '; } cout << '\n' ; } int main() { // freopen("in.txt","r",stdin); ios::sync_with_stdio(false) ; cin.tie(0) ;cout.tie(0) ; int t ; cin >> t; while(t--) solv() ; }
I. Dreamy Putata
#include<cstdio> #include<algorithm> using namespace std; const int N=100005,K=5,M=K*2+3,P=1000000007; int n,m,cnt,q,i,j,op,sx,sy,ex,ey,inv[101]; int pos[N],pl[N][K],pr[N][K],pu[N][K],pd[N][K]; int val[262155][K*2][M],A[K*2][M],B[K*2][M],C[K*2][M],g[M][M],e[M]; bool flag; const int BUF=30000000; char Buf[BUF],*buf=Buf; inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} inline int po(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;} inline void init(int v[][M],int x){ for(int i=0;i<m;i++){ v[i][i+m]=1; /* E[x,i]=(pl[x][i]*E[x,i-1]+pr[x][i]*E[x,i+1]+pu[x][i]*E[x-1,i]+pd[x][i]*E[x+1,i])/100+1 100*E[x,i]=pl[x][i]*E[x,i-1]+pr[x][i]*E[x,i+1]+pu[x][i]*E[x-1,i]+pd[x][i]*E[x+1,i]+100 pd[x][i]*E[x+1,i]=100*E[x,i]-pl[x][i]*E[x,i-1]-pr[x][i]*E[x,i+1]-pu[x][i]*E[x-1,i]-100 pd[x][i]*E[x+1,i]=100*v[i]-pl[x][i]*E[x,i-1]-pr[x][i]*E[x,i+1]-pu[x][i]*E[x-1,i]-100 */ int _inv=inv[pd[x][i]]; v[i+m][i+m]=100LL*_inv%P; v[i+m][(i-1+m)%m+m]=1LL*(P-pl[x][i])*_inv%P; v[i+m][(i+1)%m+m]=1LL*(P-pr[x][i])*_inv%P; v[i+m][i]=1LL*(P-1LL*pu[x][i])*_inv%P; v[i+m][cnt+1]=1LL*(P-100)*_inv%P; } } inline void copy(int a[][M],int b[][M]){ for(int i=0;i<cnt;i++)for(int j=0;j<=cnt+1;j++)a[i][j]=b[i][j]; } inline void merge(int f[][M],int a[][M],int b[][M]){ static int c[K*2][M]; for(int i=0;i<cnt;i++){ for(int j=0;j<=cnt+1;j++)c[i][j]=0; c[i][cnt+1]=b[i][cnt+1]; for(int j=0;j<cnt;j++)for(int k=0;k<=cnt+1;k++)c[i][k]=(1LL*b[i][j]*a[j][k]+c[i][k])%P; } copy(f,c); } void build(int x,int a,int b){ if(a==b){ pos[a]=x; init(val[x],a); return; } int mid=(a+b)>>1; build(x<<1,a,mid); build(x<<1|1,mid+1,b); merge(val[x],val[x<<1],val[x<<1|1]); } inline void change(int o){ int x=pos[o]; init(val[x],o); for(x>>=1;x;x>>=1)merge(val[x],val[x<<1],val[x<<1|1]); } void ask(int x,int a,int b,int c,int d){ if(c<=a&&b<=d){ if(!flag)flag=1,copy(B,val[x]);else merge(B,B,val[x]); return; } int mid=(a+b)>>1; if(c<=mid)ask(x<<1,a,mid,c,d); if(d>mid)ask(x<<1|1,mid+1,b,c,d); } inline void mul(int v[][M]){ static int f[M]; for(int i=0;i<cnt;i++){ int w=v[i][cnt+1]; for(int j=0;j<=cnt;j++)w=(1LL*v[i][j]*e[j]+w)%P; f[i]=w; } for(int i=0;i<cnt;i++)e[i]=f[i]; } void cal(int x,int a,int b,int c,int d){ if(c<=a&&b<=d){mul(val[x]);return;} int mid=(a+b)>>1; if(c<=mid)cal(x<<1,a,mid,c,d); if(d>mid)cal(x<<1|1,mid+1,b,c,d); } inline void gauss(){ int i,j,k; for(i=0;i<=cnt;i++){ for(j=i;j<=cnt;j++)if(g[j][i])break; if(j!=i)for(k=i;k<=cnt+1;k++)swap(g[i][k],g[j][k]); int inv=po(g[i][i],P-2); for(j=i+1;j<=cnt;j++){ int t=1LL*g[j][i]*inv%P; for(k=i;k<=cnt+1;k++)g[j][k]=(g[j][k]-1LL*g[i][k]*t)%P; } } for(i=cnt;~i;i--){ e[i]=g[i][cnt+1]; for(j=i+1;j<=cnt;j++)e[i]=(e[i]-1LL*g[i][j]*e[j])%P; e[i]=1LL*e[i]*po(g[i][i],P-2)%P; } } inline int query(int sx,int sy,int ex,int ey){ /* 0<=ex<n-1 ask A=[0,ex] ask B=[ex+1,n-1] in A: we know E(ex,ey)=0 but E(ex+1,ey) is not right, set it into itself then merge C=A+B in C: we know the last row, it equals to the first m variables we know the row after the last row, it equals to the next m variables then we know the first row, the last row and row ex, row ex+1 if sx<=ex, ask[0,sx], use row first&last to get answer if sx>ex, ask[ex+1,sx] use row ex..ex+1 to get answer */ /* ex==n-1 ask A=[0,n-1] we know the last row, it equals to the first m variables we know the row after the last row, it equals to the next m variables, except the ty-th we know E(ex,ey)=0 ask[0,sx], use row first&last to get answer */ flag=0; ask(1,0,n-1,0,ex); copy(A,B); for(int i=0;i<=cnt+1;i++)A[ey+m][i]=0; A[ey+m][cnt]=1; if(ex<n-1){ flag=0; ask(1,0,n-1,ex+1,n-1); merge(C,A,B); }else copy(C,A); for(int i=0;i<cnt;i++){ for(int j=0;j<=cnt;j++)g[i][j]=C[i][j]; g[i][i]=(g[i][i]-1+P)%P; g[i][cnt+1]=(P-C[i][cnt+1])%P; } for(int i=0;i<=cnt;i++)g[cnt][i]=A[ey][i]; g[cnt][cnt+1]=(P-A[ey][cnt+1])%P; gauss(); if(sx<=ex)cal(1,0,n-1,0,sx); else{ static int w[M]; for(int i=0;i<cnt;i++){ w[i]=A[i][cnt+1]; for(int j=0;j<=cnt;j++)w[i]=(1LL*A[i][j]*e[j]+w[i])%P; } for(int i=0;i<cnt;i++)e[i]=w[i]; cal(1,0,n-1,ex+1,sx); } return (e[sy]%P+P)%P; } int main(){ for(inv[0]=inv[1]=1,i=2;i<=100;i++)inv[i]=1LL*(P-inv[P%i])*(P/i)%P; fread(Buf,1,BUF,stdin);read(n);read(m); for(i=0;i<n;i++)for(j=0;j<m;j++)read(pl[i][j]);//(i,j-1) for(i=0;i<n;i++)for(j=0;j<m;j++)read(pr[i][j]);//(i,j+1) for(i=0;i<n;i++)for(j=0;j<m;j++)read(pu[i][j]);//(i-1,j) for(i=0;i<n;i++)for(j=0;j<m;j++)read(pd[i][j]);//(i+1,j) cnt=m*2; build(1,0,n-1); read(q); while(q--){ read(op);read(sx);read(sy); if(op==1){ read(pl[sx][sy]);read(pr[sx][sy]);read(pu[sx][sy]);read(pd[sx][sy]); change(sx); }else{ read(ex);read(ey); printf("%d\n",query(sx,sy,ex,ey)); } } }
J. Mysterious Tree
#include<bits/stdc++.h> using namespace std; int n; int ask(int u,int v) { cout << "? " << u <<' ' << v << endl ; int x ; cin >> x; return x; } void solv() { cin >> n; int u = -1, v = -1; for(int i = 1;i + 1 <= n;i += 2) { if(ask(i , i + 1) == 1) { u = i ; v = i + 1 ; break ; } } if(n & 1) { if(ask(n , n - 1)== 1) { u = n ; v = n - 1; } } if(u == -1) { cout << "! 1" << endl ; return ; } vector<int> vec; for(int i = 1;i <= n;i++) { if(i != u && i != v) vec.push_back(i) ; } if(!ask(u , vec[0])) { if(!ask(v , vec[0])) { cout << "! 1" << endl ; return ; } swap(u , v); } if(ask(u , vec[1])) { cout << "! 2" << endl ; return ; } cout << "! 1" << endl ; return ; } int main () { int t ; cin >> t; while(t--) solv() ; }
K. Card Game
#include<bits/stdc++.h> using namespace std; const int N = 3e5 + 5; int a[N] ; int ch[N * 60][2] ; int tag[N * 60] ; int cnt = 0; int n , q; int rt[N] ; int build(int l,int r) { int c = ++cnt ; tag[c] = 0; if(l == r) return c; ch[c][0] = build(l , (l + r >> 1)) ; ch[c][1] = build((l + r >> 1) + 1, r); return c; } int modify(int x,int y,int ql,int qr,int l,int r,int tagx,int tagy) { /// [ql,qr]继承x , ++ , < ql继承x , >qr继承y if(ql <= l && r <= qr) { int c = ++cnt ; ch[c][0] = ch[x][0]; ch[c][1] = ch[x][1] ; tag[c] = tag[x] + tagx + 1; // printf("on %d %d , tag %d\n",l,r,tag[c]) ; return c; } else if(r < ql) { int c = ++cnt ; ch[c][0] = ch[x][0]; ch[c][1] = ch[x][1]; tag[c] = tagx + tag[x]; return c; } else if(l > qr) { int c = ++cnt ; ch[c][0] = ch[y][0]; ch[c][1] = ch[y][1]; tag[c] = tagy + tag[y]; return c; } else { int md = (l + r >> 1) ; int c = ++cnt ; ch[c][0] = modify(ch[x][0] , ch[y][0] , ql , qr , l , md , tagx + tag[x] , tagy + tag[y]) ; ch[c][1] = modify(ch[x][1] , ch[y][1] , ql , qr , md + 1 , r , tagx + tag[x] , tagy + tag[y]) ; return c; } } int qval(int rt,int pos,int l,int r) { if(l == r) return tag[rt] ; int md = (l + r >> 1) ; if(pos <= md) return tag[rt] + qval(ch[rt][0] , pos , l , md) ; else return tag[rt] + qval(ch[rt][1] , pos , md + 1, r) ; } int nxt[N] ; int main() { // freopen("in.txt","r",stdin) ; // freopen("out2.txt","w",stdout) ; ios::sync_with_stdio(false) ; cin.tie(0) ; cin >> n >> q; for(int i = 1;i <= n;i++) cin >> a[i] ; for(int i = 1;i <= n;i++) nxt[i] = n + 1; rt[n + 1] = build(1 , n) ; for(int i = n;i >= 1;i--) { // printf("on %d\n" , i) ; rt[i] = modify(rt[i + 1] , rt[min(n+1 , nxt[a[i]] + 1)] , i , nxt[a[i]] - 1, 1 , n , 0 , 0) ; nxt[a[i]] = i; } // cout << qval(rt[3] , 4 , 1 , n) << '\n' ; int lans = 0; while(q--) { int l , r; cin >> l >> r; l ^= lans ; r ^= lans; cout << (lans = qval(rt[l] , r , 1 , n)) << '\n' ; } return 0; }
L. Master of Both V
#include<bits/stdc++.h> using namespace std; using ll=long long; #define fs first #define sd second const int N=5e5+1e3+7; struct P { int x,y; }a[N],b[N]; bool operator <(const P &a,const P &b) { return a.x<b.x||(a.x==b.x&&a.y<b.y); } bool operator ==(const P &a,const P &b) { return !(a<b)&&!(b<a); } P operator -(const P &a,const P &b) { return {a.x-b.x,a.y-b.y}; } ll operator *(const P &a,const P &b) { return 1ll*a.x*b.y-1ll*a.y*b.x; } ll operator ^(const P &a,const P &b) { return 1ll*a.x*b.x+1ll*a.y*b.y; } using L=pair<P,P>; int T,n; L mod[N]; tuple<int,int,int> e[N]; int to[N]; int phase(const P &a) { if(a.y!=0) return a.y<0; return a.x<0; } bool cmp(const P &a,const P &b) { int pa=phase(a),pb=phase(b); if(pa!=pb) return pa<pb; return a*b>0; } struct T{ L lv,rv; int ok,cnt; }t[N*4+1]; bool chk(const L &a,const L &b) { if(a==b) return 1; P u=a.sd-a.fs,v=b.sd-b.fs,w=b.fs-a.sd; if(w.x==0&&w.y==0) return u*v>0; return (u*w>0||(u*w==0&&(u^w)>0))&&(w*v>0||(w*v==0&&(w^v)>0)); } void update(int x) { if(!t[x<<1].cnt) t[x]=t[x<<1|1]; else if(!t[x<<1|1].cnt) t[x]=t[x<<1]; else { t[x].lv=t[x<<1].lv,t[x].rv=t[x<<1|1].rv; t[x].ok=t[x<<1].ok&&t[x<<1|1].ok&&chk(t[x<<1].rv,t[x<<1|1].lv); t[x].cnt=t[x<<1].cnt+t[x<<1|1].cnt; } } int id[N]; int st[N]; multiset<P> seg[N]; void adj(L &a,L b) { ll f=(a.sd-a.fs)*(b.fs-a.fs); if(f) { if(f<0) swap(a.fs,a.sd); } else { f=(a.sd-a.fs)*(b.sd-a.fs); if(f<0) swap(a.fs,a.sd); } } int m; void modify(int p,L u) { int x=p+m-1; if(u.fs==u.sd) t[x].cnt=0; else t[x].ok=1,t[x].cnt=1,t[x].lv=t[x].rv=u; x>>=1; while(x) { update(x); x>>=1; } } struct MODIFY{ int r; L u; int c; }; vector<MODIFY> ch[N],rch[N]; signed main() { ios::sync_with_stdio(false); cin.tie(0); cin>>T; while(T--) { cin>>n; vector<tuple<int,int,int> >X; for(int i=1;i<=n;i++) { string op; cin>>op; if(op=="+") { cin>>a[i].x>>a[i].y>>b[i].x>>b[i].y; ll A=a[i].y-b[i].y,B=b[i].x-a[i].x,C=-1ll*b[i].y*a[i].x+1ll*a[i].y*b[i].x; ll g=__gcd(__gcd(A,B),C); A/=g,B/=g,C/=g; if(A<0||(A==0&&B<0)) A*=-1,B*=-1,C*=-1; g=abs(__gcd(A,B)); e[i]={A,B,C}; X.push_back(e[i]); } else { cin>>a[i].x; a[i].y=0; b[i]=a[i]; } } sort(X.begin(),X.end()); X.erase(unique(X.begin(),X.end()),X.end()); for(int i=1;i<=X.size();i++) seg[i].clear(),st[i]=0; for(int i=1;i<=n;i++) ch[i].clear(),rch[i].clear(); for(int i=1;i<=n;i++) { if(a[i]==b[i]) { int x=id[a[i].x]; id[i]=x; int j=a[i].x; seg[x].erase(seg[x].find(a[j])); seg[x].erase(seg[x].find(b[j])); ch[st[x]].push_back({i-1,mod[st[x]],x}); if(!seg[x].size()) st[x]=0; else st[x]=i,mod[i]={*seg[x].begin(),*--seg[x].end()}; } else { id[i]=lower_bound(X.begin(),X.end(),e[i])-X.begin()+1; int x=id[i]; seg[x].insert(a[i]),seg[x].insert(b[i]); mod[i]={*seg[x].begin(),*--seg[x].end()}; if(st[x]) ch[st[x]].push_back({i-1,mod[st[x]],x}); st[x]=i; } } for(int i=1;i<=X.size();i++) if(st[i]) { ch[st[i]].push_back({n,mod[st[i]],i}); mod[n+1]=mod[st[i]]; } MODIFY mx,smx,rem; mx.r=smx.r=-1; rem.c=-1; for(int i=1;i<=n;i++) { if(!ch[i].size()) continue; if(rem.c!=-1) { if(rem.r>=i) ch[i].push_back(rem); rem.c=-1; } sort(ch[i].begin(),ch[i].end(),[&](const MODIFY &u,const MODIFY &v){return u.r>v.r;}); for(auto [r,u,c]:ch[i]) { MODIFY v={r,u,c}; if(v.r>mx.r) swap(mx,v); if(v.r>smx.r) swap(smx,v); if(mx.c==smx.c) swap(v,smx); } for(auto [r,u,c]:ch[i]) { MODIFY dir; if(mx.c!=c) dir=mx; else if(smx.c!=c) dir=smx; else dir.c=-1; if(dir.c==-1||dir.r<i) rem={r,u,c}; else { adj(u,dir.u); rch[i].push_back({min(dir.r,r),u,c}); if(dir.r<r) ch[dir.r+1].push_back({r,u,c}); } } } vector<P> v; for(int i=1;i<=n;i++) for(auto [r,u,c]:rch[i]) v.push_back({u.sd-u.fs}); sort(v.begin(),v.end(),cmp); vector<int> ct(v.size()); for(int i=1;i<=n;i++) ch[i].clear(); for(int i=1;i<=n;i++) for(auto [r,u,c]:rch[i]) { int p=lower_bound(v.begin(),v.end(),u.sd-u.fs,cmp)-v.begin(); ++ct[p]; ch[i].push_back({p+ct[p],u,c}); ch[r+1].push_back({-(p+ct[p]),u,c}); } m=1; while(m<v.size()) m<<=1; for(int i=1;i<=m*2-1;i++) t[i].cnt=0,t[i].ok=1; for(int i=1;i<=n;i++) { for(auto [r,u,c]:ch[i]) { if(r>0) modify(r,u); else modify(-r,{{0,0},{0,0}}); } if(t[1].cnt<=1||(t[1].ok&&chk(t[1].rv,t[1].lv))) cout<<1; else cout<<0; } cout<<"\n"; } }
M. V-Diagram
#include <bits/stdc++.h> using namespace std; using i64 = int64_t; using f64 = double_t; int main() { cin.tie(nullptr)->sync_with_stdio(0); cout << fixed << setprecision(20); int t; cin >> t; for (int ti = 0; ti < t; ti += 1) { int n; cin >> n; vector<i64> a(n); for (i64& ai : a) { cin >> ai; } int m = min_element(a.begin(), a.end()) - a.begin(); for (int i = 1; i < n; i += 1) { a[i] += a[i - 1]; } f64 ans = 0; ans = max(ans, (f64)a.back() / n); ans = max(ans, ((f64)a.back() - (m > 1 ? a[m - 2] : 0)) / (n - m + 1)); ans = max(ans, (f64)a[m + 1] / (m + 2)); cout << ans << "\n"; } }