2023 China Collegiate Programming Contest (CCPC) Guilin Onsite (The 2nd Universal Cup. Stage 8: Guilin)
题解:
https://files.cnblogs.com/files/clrs97/2023Guilin_Tutorial.pdf
Code:
A. Easy Diameter Problem
#include<bits/stdc++.h> using namespace std; const int N = 300 ; const int mod = 1e9 + 7; typedef pair<int,int> pii; vector<pair<int,int> > E[N + 5]; int t[N*2 + 5 ] , rt[ N*2 + 5]; 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; } int n ; vector<vector<int> > f[N / 2][N * 2] ; ///长度,中心所在点,完整子树标号,可以放置的节点L个 void upd(int &x,int y) { ((x += y) >= mod ? (x -= mod) : 0) ; } void upd(int i,int j,int k,int l,int y) { // if(i==0&&j==10) printf("%d %d %d %d , %d\n",i,j,k,l,y) ; if(f[i][j].size() <= k) f[i][j].resize(k + 1) ; if(f[i][j][k].size() <= l) f[i][j][k].resize(l + 1) ; upd(f[i][j][k][l] , y) ; return ; } int C(int a,int b) { if(a < b) return 0; return 1LL * t[a] * rt[b] % mod * rt[a - b] % mod; } int Cm(int a,int b) { if(a == 0 && b == 0) return 1; return C(a + b - 1 ,b); } int put(int n,int k) ///n个位置,可重,有序地放入k个物品 { return 1LL*C(n + k - 1 , k)*t[k] % mod; } vector<int> num[N + 5][N + 5] ; ///i号点,深度为j,0~size方向的子树大小,最后一位代表总大小 pii edges[N + 5]; ///边 int be[N + 5][2] ; ///边在vector中的id(.first , .second) void calc(int i,int j,int k,int l) ///长度,中心所在点,完整子树标号,可以放置的节点L个 { int ca ; if(k != -1 ) ca = f[i][j][k][l] ; else ca = 1; // if(k == -1) printf("MID %d\n", j ); // printf("Ans %d %d %d %d , %d\n",i,j,k,l,ca) ; // if(j <= n && k != -1) printf("Sub %d\n" , E[j][k]) ; // else if(k != -1) printf("Sub point %d %d\n" , edges[j - n].first , edges[j - n].second) ; if(j <= n) { int cnt = 0; for(auto [v,id] : E[j]) { if(cnt == k) { int other_cnt = num[j][i].back() - num[j][i][cnt] ; for(int m = 1; m <= other_cnt ; m++) { upd(i - 1 ,id + n , edges[id].second == j , m , 1LL * ca * Cm(l , other_cnt - m) % mod * t[other_cnt] % mod) ; } } else { int other , ne ; if(k != -1) { other = num[j][i].back()-num[j][i][cnt]-num[j][i][k]; ne = num[j][i][k] ; } else { other = num[j][i].back() - num[j][i][cnt] ; ne = 0; } upd(i - 1 , id + n , edges[id].second == j , l + other + ne, 1LL * ca * t[ne] % mod * Cm(l + ne + 1, other) % mod * t[other] % mod) ; } cnt++; } } else { // puts("injbk") ; for(int cnt = 0;cnt < 2;cnt++) { int to_id , ano_id; if(cnt == 0) to_id = edges[j - n].first , ano_id = edges[j - n].second; else to_id = edges[j - n].second , ano_id = edges[j - n].first; // printf("CNT %d\n" , cnt) ; if(cnt == k) { int other = num[ano_id][i].back() - num[ano_id][i][be[j - n][cnt ^ 1]] ; for(int m = 1;m <= other;m++) { upd(i , to_id , be[j - n][cnt] , m , 1LL * ca * Cm(l , other - m) % mod * t[other] % mod) ; } } else { // printf("%d %d , %d %d\n",ano_id , i , num[ano_id][i].size() , be[j - n][cnt]) ; int ne = num[ano_id][i].back() - num[ano_id][i][be[j - n][cnt ^ 1]] ; // puts("OK") ; // printf("%d goto %d , %d , %d\n",j,to_id,be[j][cnt] , E[to_id][be[j][cnt]]) ; upd(i , to_id , be[j - n][cnt] , l + ne , 1LL * ca * t[ne] % mod ); } // printf("CNT %d\n" , cnt) ; } } } int dis[N + 5]; int bfs(int u) { for(int i = 1;i <= n;i++) dis[i] = 1e9; dis[u] = 1; queue<int> q;q.push(u) ; while(q.size()) { int x = q.front() ; q.pop() ; for(auto [v,w] : E[x]) { if(dis[v] > dis[x] + 1) { dis[v] = dis[x] + 1; q.push(v) ; } } } int mx = 1; for(int i = 2;i <= n;i++) { if(dis[i] > dis[mx]) mx = i; } return mx; } vector<int> nodes ; bool dfs(int fa,int u,int v) { if(u == v) { nodes.push_back(v) ; return 1; } for(auto [x,w] : E[u]) { if(x != fa) { if(dfs(u , x , v)) { nodes.push_back(u) ; return 1; } } } return 0; } int siz[N + 5][N + 5]; void dfs_s(int fa,int u) { siz[u][0] = 1; for(auto [v,w] : E[u]) { if(v != fa) { dfs_s(u , v) ; for(int l = 1;l <= n && siz[v][l - 1];l++) { siz[u][l] += siz[v][l - 1] ; } } } } int main() { ios::sync_with_stdio(false) ; cin.tie(0) ; cin >> n; if(n <= 3) { cout << fpow(2 , n - 1) << '\n' ; return 0; } map<pii,int> mp; for(int i = 1;i < n;i++) { int u , v;cin >> u >> v; E[u].push_back({v , i}) ; E[v].push_back({u , i}) ; mp[{u , v}] = mp[{v , u}] = i; edges[i] = {u , v} ; be[i][0] = E[u].size() - 1; be[i][1] = E[v].size() - 1; } t[0] = rt[0] = 1; for(int i = 1;i <= n*2 + 1;i++) t[i] = 1LL*t[i - 1]*i % mod, rt[i] = fpow(t[i] , mod - 2) ; int u = bfs(1) ; int v = bfs(u) ; dfs(0 , u , v); for(int i = 1;i <= n;i++) { memset(siz,0,sizeof(siz)) ; dfs_s(0 , i) ; for(int j = 0; siz[i][j] && j <= n; j++) { num[i][j].resize(E[i].size() + 1) ; if(j) { for(int k = 0;k < E[i].size();k++) num[i][j][k] = siz[E[i][k].first][j - 1] ; } num[i][j].back() = siz[i][j] ; } } int L ; if(nodes.size() & 1) { calc( nodes.size() / 2 ,nodes[nodes.size() / 2] , -1 , 0) ; } else { calc(nodes.size() / 2 - 1 ,n + mp[{nodes[nodes.size() / 2] , nodes[nodes.size()/2 - 1]}] , -1 , 0) ; } // puts("OJBK") ; for(int i = nodes.size()/2 - 1; i >= 1; i--) { for(int j = n + n - 1;j >= 1;j--) { for(int k = 0;k < f[i][j].size();k++) { for(int l = 0;l < f[i][j][k].size();l++) { if(f[i][j][k][l]) calc(i , j , k , l) ; } } } } int ans = 0; for(int j = n + 1 ; j <= n*2 - 1 ; j++) { for(int k = 0 ; k < 2 && k < f[0][j].size();k++) { for(int l = 0;l < f[0][j][k].size();l++) { ans = (ans + 1LL * f[0][j][k][l] * 2) % mod ; // printf("F %d %d %d , %d\n",j,k,l,f[0][j][k][l]) ; } } } cout << ans << '\n' ; return 0; }
B. The Game
#include<bits/stdc++.h> using namespace std; int n , m; int a[300005] , b[300005]; typedef long long ll; void solv() { cin >> n >> m; for(int i = 1;i <= n;i++) cin >> a[i] ; for(int i = 1;i <= m;i++) cin >> b[i] ; sort(a + 1 , a + n + 1) ; sort(b + 1 , b + m + 1) ; ll sum = 0; for(int i = m;i >= 1;i--) { if(a[n-(m-i)] > b[i]) { cout << -1 << '\n' ; return ; } sum += (b[i] - a[n-(m-i)]) ; } if(sum > n - m) { cout << -1 << '\n' ; return ; } vector<int> ans; int ndel = (n - m) - sum; multiset<int> st; for(int i = 1;i <= n;i++) st.insert(a[i]) ; // int cb1 = 0; // for(int i = 1;i <= m;i++) cb1 += (b[i] == b[1]) ; while(ndel > 0) { for(int i = 1;i <= ndel;i++) { int x = *st.begin(); ans.push_back(x) ; st.erase(st.begin()) ; st.insert(x + 1) ; st.erase(st.begin()) ; } vector<int> a(st.begin() , st.end()) ; sum = 0; for(int i = a.size() - m;i < a.size();i++) { if(a[i] > b[i - (a.size()-m) + 1]) { cout << -1 << '\n' ; return ; } sum += b[i - (a.size()-m) + 1] - a[i] ; } ndel = (a.size() - m) - sum ; } vector<int> a(st.begin() , st.end()) ; sum = 0; for(int i = a.size() - m;i < a.size();i++) { if(a[i] > b[i - (a.size()-m) + 1]) { cout << -1 << '\n' ; return ; } int t = (i - (a.size()-m)+1) ; while(a[i] < b[t]) { ans.push_back(a[i]) ; a[i]++; } } cout << ans.size() << '\n' ; for(auto &x : ans) cout << x <<' ' ; 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() ; }
C. Master of Both IV
#include<bits/stdc++.h> using namespace std; const int N=2e5+1e3+7,P=998244353; int T,a[N],n,c[N]; struct LB{ int a[21]; void clear() { memset(a,0,sizeof(a)); } int ins(int x) { for(int i=20;i>=0;i--) { if(!(x>>i&1)) continue; if(!a[i]) { a[i]=x; return 1; } else x^=a[i]; } return 0; } }e; vector<int> fac[N]; int pw[N]; int main() { pw[0]=1; for(int i=1;i<=200000;i++) pw[i]=pw[i-1]*2%P; for(int i=1;i<=200000;i++) for(int j=i*2;j<=200000;j+=i) fac[j].push_back(i); scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) c[i]=0; e.clear(); int f=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]),c[a[i]]++,f+=!e.ins(a[i]); int ans=pw[f]-1; for(int i=1;i<=n;i++) { if(!c[i]) continue; int f=0; e.clear(); for(auto j:fac[i]) { if(!c[j]) continue; f+=!e.ins(j); f+=c[j]-1; } ans=(ans+pw[f+c[i]-1])%P; } printf("%d\n",ans); } }
D. Subway
#include<bits/stdc++.h> using namespace std; const int B=10001,hf=5001;//+(-1,hf),+(-k*2,k*B) int main() { int n; cin>>n; vector<tuple<int,int,int>> a(n+5); int maxa=0; for(int i=1;i<=n;i++) { int x,y,c; cin>>x>>y>>c; maxa=max(maxa,c); a[i]={x,y,c}; } sort(a.begin()+1,a.begin()+n+1); vector<vector<pair<int,int>>> lines(maxa); for(int k=0;k<maxa;k++) { for(int i=1;i<=n;i++) { auto [x,y,c]=a[i]; if(k<c) { lines[k].emplace_back(x,y); } lines[k].emplace_back(x-1-k*2,y+hf+k*B); } } cout<<lines.size()<<endl; for(auto &line:lines) { cout<<line.size(); for(auto [x,y]:line)cout<<' '<<x<<' '<<y; cout<<endl; } return 0; }
E. Prefix Mahjong
#include <bits/stdc++.h> using namespace std; constexpr int magic = 18; struct Matrix { array<unsigned, magic> r; Matrix() { r.fill(0); } }; Matrix operator*(const Matrix &lhs, const Matrix &rhs) { Matrix res; for (int i = 0; i < 9; i += 1) { if (lhs.r[i]) { for (int j = 0; j < 9; j += 1) { if ((lhs.r[i] >> (j + 9)) % 2) { res.r[i] |= rhs.r[j]; } if ((lhs.r[i] >> j) % 2) { res.r[i] |= rhs.r[j] >> 9; } } } } return res; } int main() { cin.tie(nullptr)->sync_with_stdio(false); array<Matrix, magic> base; for (int i = 0; i < magic; i += 1) { for (int x = 0; x < magic; x += 1) { for (int y = 9; y < magic; y += 1) { int x0 = x % 3, x1 = x / 3 % 3, x2 = x / 9; int y0 = y % 3, y1 = y / 3 % 3, y2 = y / 9; if (y2 < x2) { continue; } if (x0 != y1) { continue; } int k = (y2 > x2 ? 2 : 0) + (x1 + x0 + y0); if (i >= k and (i - k) % 3 == 0) { base[i].r[y - 9] |= 1 << x; } } } } int t; cin >> t; for (int ti = 0; ti < t; ti += 1) { int n; cin >> n; set<int> s; vector<int> p(n); for (int &pi : p) { cin >> pi; s.insert(pi); s.insert(pi + 1); } int m = 0; map<int, int> mp; for (int x : s) { mp[x] = m++; } for (int &pi : p) { pi = mp[pi]; } int k = 1; while (k < m) { k <<= 1; } vector<Matrix> seg(k << 1, base[0]); vector<int> c(m); for (int pi : p) { c[pi] += 1; while (c[pi] >= magic) { c[pi] -= 3; } int i = pi + k; seg[i] = base[c[pi]]; for (i /= 2; i; i /= 2) { seg[i] = seg[i * 2] * seg[i * 2 + 1]; } cout << seg[1].r[0] % 2; } cout << "\n"; } }
F. Redundant Towers
#include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef pair<int,int>E; const int N=100005,M=215; int n,k,q,i,j,x,L,R,last,at[N],pos[N];bool adj[N][9]; struct P{int x,y,id;bool on;}p[N]; struct Node{ int predeg,w,ori; Node(){} Node(int _predeg,int _w,int _ori){ predeg=_predeg; w=_w; ori=_ori; } }; struct Graph{ int leaf,n; vector<Node>nodes; vector<E>edges; }val[262155]; namespace Solver{ int n,nowleaf; int predeg[M],w[M],ori[M],isvip[M]; int g[M],v[M],nxt[M],ed; int deg[M],dfn[M],low[M],q[M],t,num,sub,all; int ct,cv,newid[M]; int _g[M],_v[M],_nxt[M],_ed; int G[M],V[M],NXT[M],ED; int fa[M],dep[M],id[M]; Node tree[M]; inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} inline void ADD(int x,int y){ deg[y]++; V[++ED]=y; NXT[ED]=G[x]; G[x]=ED; V[++ED]=x; NXT[ED]=G[y]; G[y]=ED; } void tarjan(int x,int f){ dfn[x]=low[x]=++num; q[++t]=x; for(int i=g[x];i;i=nxt[i])if(!dfn[v[i]]){ int y=v[i]; tarjan(y,x); if(low[x]>low[y])low[x]=low[y]; if(!f)sub++; if(dfn[x]<=low[y]&&f||!f&&sub>1){ ADD(++all,x); while(1){ int z=q[t--]; ADD(all,z); if(z==y)break; } } }else if(low[x]>dfn[v[i]])low[x]=dfn[v[i]]; } inline void addedge(int x,int y){ if(x>0)swap(x,y); x*=-1; _v[++_ed]=y; _nxt[_ed]=_g[x]; _g[x]=_ed; } void dfs(int x,int y){ int d=0; dep[x]=dep[y]+1; fa[x]=y; for(int i=G[x];i;i=NXT[i]){ int u=V[i]; if(u==y)continue; dfs(u,x); if(!id[u]){ if(x<=n)predeg[x]++; }else{ d++; id[x]^=id[u]; } } if(!d&&(x>n||!isvip[x])){ if(x<=n&°[x]+predeg[x]<=1)nowleaf+=w[x]; return; } if(d<2&&(x>n||!isvip[x]))return; id[x]=x; if(x<=n){ tree[++ct]=Node(predeg[x],w[x],ori[x]); newid[x]=ct; }else{ cv++; newid[x]=-cv; } int X=newid[x]; for(int i=G[x];i;i=NXT[i]){ int u=V[i]; if(u==y)continue; int t=id[u]; if(!t)continue; int len=dep[t]-dep[x]; int Y=newid[t]; if(len==1){ addedge(X,Y); }else if(len==2){ if(x<=n){ //X-O-X cv++; addedge(X,-cv); addedge(-cv,Y); }else{ int mid=fa[t]; if(predeg[mid]){ //O-X-O // | tree[++ct]=Node(0,0,0); }else{ //O-X-O tree[++ct]=Node(0,w[mid],0); } addedge(X,ct); addedge(ct,Y); } }else{ int sum=0; for(int j=fa[t];j!=x;j=fa[j])if(j<=n&&!predeg[j])sum+=w[j]; if(len&1){ cv++; tree[++ct]=Node(0,sum,0); addedge(ct,-cv); if(x<=n){ //X-O-X-O //X-O-X-O-X-O-... addedge(X,-cv); addedge(ct,Y); }else{ //O-X-O-X //O-X-O-X-O-X-... addedge(X,ct); addedge(-cv,Y); } }else{ if(x<=n){ //X-O-X-O-X //X-O-X-O-X-O-X... cv+=2; tree[++ct]=Node(0,sum,0); addedge(X,-cv+1); addedge(-cv+1,ct); addedge(ct,-cv); addedge(-cv,Y); }else{ //O-X-O-X-O //O-X-O-X-O-X-O... tree[++ct]=Node(0,sum,0); addedge(X,ct); addedge(ct,Y); } } } } } inline void compress(Graph&res){ int i; all=n; num=0; for(i=1;i<=n;i++){ dfn[i]=0; deg[i]=0; } for(i=1;i<=n;i++)if(!dfn[i]){ sub=0; t=0; tarjan(i,0); if(t>1){ all++; while(t)ADD(all,q[t--]); } } ct=cv=0; _ed=0; for(i=1;i<=n;i++){ if(!isvip[i])continue; if(dep[i])continue; dfs(i,0); } for(i=1;i<=n;i++){ if(dep[i])continue; if(deg[i]+predeg[i]<=1)nowleaf+=w[i]; } res.edges.clear(); for(i=1;i<=cv;i++){ int last=0,st=0,len=0; for(int j=_g[i];j;j=_nxt[j]){ int o=_v[j]; if(!st)st=o;else res.edges.push_back(E(last,o)); last=o; len++; } if(len>2)res.edges.push_back(E(st,last)); _g[i]=0; } ED=0; for(i=1;i<=all;i++){ G[i]=0; dep[i]=0; id[i]=0; } res.leaf=nowleaf; res.n=ct; res.nodes.resize(ct+1); for(i=1;i<=ct;i++)res.nodes[i]=tree[i]; } inline void init(Graph&graph,int x){ graph.leaf=0; graph.edges.clear(); if(!p[x].on){ graph.n=0; graph.nodes.clear(); }else{ graph.n=1; graph.nodes.resize(2); graph.nodes[1]=Node(0,1,x); } } inline void merge(int o,int l,int mid,int r){ const Graph&A=val[o<<1]; const Graph&B=val[o<<1|1]; nowleaf=A.leaf+B.leaf; int ca=A.n,cb=B.n,i; n=ca+cb; for(i=1;i<=ca;i++){ predeg[i]=A.nodes[i].predeg; w[i]=A.nodes[i].w; ori[i]=A.nodes[i].ori; } for(i=1;i<=cb;i++){ predeg[i+ca]=B.nodes[i].predeg; w[i+ca]=B.nodes[i].w; ori[i+ca]=B.nodes[i].ori; } for(i=1;i<=n;i++)pos[ori[i]]=i; ed=0; for(i=1;i<=n;i++)isvip[i]=g[i]=0; for(vector<E>::const_iterator it=A.edges.begin();it!=A.edges.end();it++){ add(it->first,it->second); add(it->second,it->first); } for(vector<E>::const_iterator it=B.edges.begin();it!=B.edges.end();it++){ add(it->first+ca,it->second+ca); add(it->second+ca,it->first+ca); } for(i=l;i<=r&&i-l<=k;i++){ int x=pos[i]; if(x)isvip[x]=1; } for(i=r;i>=l&&r-i<=k;i--){ int x=pos[i]; if(x)isvip[x]=1; } for(i=mid+1;i<=r&&i-mid-1<=k;i++){ int x=pos[i]; if(!x)continue; for(int j=max(l,i-k);j<=mid;j++){ if(!adj[i][i-j])continue; int y=pos[j]; if(!y)continue; add(x,y); add(y,x); } } for(i=1;i<=n;i++)pos[ori[i]]=0; compress(val[o]); } } namespace Tarjan{ int n,pre[M],w[M],g[M],v[M],nxt[M],ed; int dfn[M],low[M],q[M],num,t,sub,notcut; inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} void tarjan(int x,int f){ dfn[x]=low[x]=++num; q[++t]=x; bool iscut=0; for(int i=g[x];i;i=nxt[i])if(!dfn[v[i]]){ int y=v[i]; tarjan(y,x); if(low[x]>low[y])low[x]=low[y]; if(!f)sub++; if(dfn[x]<=low[y]&&f||!f&&sub>1){ iscut=1; while(1){ int z=q[t--]; if(z==y)break; } } }else if(low[x]>dfn[v[i]])low[x]=dfn[v[i]]; if(!iscut){ int deg=!!g[x]; deg+=pre[x]; if(deg<=1)notcut+=w[x]; } } inline int cal(const Graph&graph){ notcut=graph.leaf; n=graph.n; int i; for(i=1;i<=n;i++){ pre[i]=graph.nodes[i].predeg; w[i]=graph.nodes[i].w; g[i]=dfn[i]=0; } ed=0; for(vector<E>::const_iterator it=graph.edges.begin();it!=graph.edges.end();it++){ add(it->first,it->second); add(it->second,it->first); } for(i=1;i<=n;i++)if(!dfn[i]){ sub=0; t=0; tarjan(i,0); } return notcut; } } inline bool cmp(const P&A,const P&B){return A.x<B.x;} inline long long mysqr(int x){return 1LL*x*x;} inline bool check(const P&A,const P&B){ return mysqr(A.x-B.x)+mysqr(A.y-B.y)<=mysqr(k); } void build(int x,int a,int b){ if(a==b){ Solver::init(val[x],a); return; } int mid=(a+b)>>1; build(x<<1,a,mid); build(x<<1|1,mid+1,b); Solver::merge(x,a,mid,b); } void change(int x,int a,int b,int c){ if(a==b){ Solver::init(val[x],a); return; } int mid=(a+b)>>1; if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c); Solver::merge(x,a,mid,b); } int main(){ scanf("%d%d",&n,&k); for(i=1;i<=n;i++){ scanf("%d%d",&p[i].x,&p[i].y); p[i].id=i; p[i].on=1; } sort(p+1,p+n+1,cmp); for(i=1;i<=n;i++)at[p[i].id]=i; for(i=1;i<=n;i++)for(j=max(i-k,1);j<i;j++)if(check(p[i],p[j]))adj[i][i-j]=1; build(1,1,n); scanf("%d",&q); last=0; while(q--){ scanf("%d",&x);x^=last; x=at[x]; p[x].on^=1; change(1,1,n,x); last=Tarjan::cal(val[1]); printf("%d\n",last); } }
G. Hard Brackets Problem
#include<bits/stdc++.h> using namespace std; const int N=2e5+1e3+7,P=998244353; int T; string s; int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>T; while(T--) { cin>>s; int mn=0,f=0; for(int i=(int)s.size()-1;i>=0;i--) { if(s[i]==')') f++; else f--; mn=min(mn,f); } if(mn<0) cout<<"impossible\n"; else cout<<s<<"\n"; } }
H. Sweet Sugar
#include<cstdio> #define rep(i) for(int i=0;i<2;i++) const int N=1000005,inf=100000000; int Case,n,m,i,x,y,w[N],g[N],v[N<<1],nxt[N<<1],ed,ans,f[N][2],h[2];bool cut[N]; inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} inline void up(int&a,int b){a<b?(a=b):0;} void dfs(int x,int y){ rep(j)f[x][j]=-inf; f[x][w[x]&1]=w[x]; for(int i=g[x];i;i=nxt[i]){ int u=v[i]; if(u==y)continue; dfs(u,x); if(cut[u])continue; rep(j)h[j]=f[x][j]; rep(j)rep(k)up(h[j^k],f[x][j]+f[u][k]); rep(j)f[x][j]=h[j]; } if(f[x][m&1]>=m)cut[x]=1,ans++; } int main(){ scanf("%d",&Case); while(Case--){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("%d",&w[i]); for(i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x); dfs(1,0); printf("%d\n",ans); for(ed=ans=i=0;i<=n;i++)g[i]=cut[i]=0; } }
I. Barkley II
#include<bits/stdc++.h> using namespace std; const int N=5e5+1e3+7,P=998244353; int T,a[N],n,m; struct DS{ int c[N]; void clear() { fill(c+1,c+n+1,0); } void add(int x,int v) { while(x) { c[x]+=v; x-=x&-x; } } int qry(int x) { int ret=0; while(x<=n) { ret+=c[x]; x+=x&-x; } return ret; } }col; int la[N],b[N],ls[N]; int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); m=min(m,n); m++; vector<int> X; for(int i=1;i<=n;i++) scanf("%d",&a[i]),X.push_back(a[i]); sort(X.begin(),X.end()); for(int i=1;i<=n;i++) b[i]=lower_bound(X.begin(),X.end(),a[i])-X.begin()+1; fill(la+1,la+n+2,0); fill(ls+1,ls+n+2,0); col.clear(); int ans=-1; for(int i=1;i<=n;i++) { if(a[i]<=n+1) ls[a[i]]=i; int L=la[b[i]]+1; int R=i-1; if(i!=1) ans=max(ans,col.qry(L)-X[b[i]-1]); if(la[b[i]]) col.add(la[b[i]],-1); col.add(i,1); la[b[i]]=i; } for(int i=1;i<=n+1;i++) ans=max(ans,col.qry(ls[i]+1)-i); printf("%d\n",ans); } }
J. The Phantom Menace
#include<bits/stdc++.h> using namespace std; using ull=unsigned long long; using pii=pair<int,int>; const int N=4e6+1e3+7; constexpr uint64_t P = (1ull<<61) - 1, bs = 1313131; uint64_t mul(uint64_t a, uint64_t b){ uint64_t l1 = (uint32_t)a, h1 = a>>32, l2 = (uint32_t)b, h2 = b>>32; uint64_t l = l1*l2, m = l1*h2 + l2*h1, h = h1*h2; uint64_t ret = (l&P) + (l>>61) + (h << 3) + (m >> 29) + (m << 35 >> 3) + 1; ret = (ret & P) + (ret>>61); ret = (ret & P) + (ret>>61); return ret-1; } ull add(const ull &a, const ull &b) { return a + b >= P ? a + b - P : a + b; } ull pw[N]; ull geth(const vector<ull> &h,int l,int r) { return add(h[r],P-mul(h[l-1],pw[r-l+1])); } int T,n,m; string s[N],t[N]; namespace Graph { int n; vector<pii> g[N]; vector<int> st; int in[N],use[N]; void dfs(int x) { while(use[x]<g[x].size()) { auto [v,id]=g[x][use[x]]; use[x]++; dfs(v); st.push_back(id); } } vector<int> Euler() { fill(in,in+n,0); fill(use,use+n,0); for(int i=0;i<n;i++) for(auto [v,id]:g[i]) in[v]++; for(int i=0;i<n;i++) if(in[i]!=g[i].size()) return {}; for(int i=0;i<n;i++) if(g[i].size()) { st.clear(); dfs(i); reverse(st.begin(),st.end()); return st; } return {}; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>T; unordered_map<ull,int>pre,suf; while(T--) { cin>>n>>m; pw[0]=1; for(int i=1;i<=m;i++) pw[i]=mul(pw[i-1],bs); for(int i=1;i<=n;i++) { cin>>s[i]; s[i]=' '+s[i]; } for(int i=1;i<=n;i++) { cin>>t[i]; t[i]=' '+t[i]; } vector<vector<ull> >hs(n+1,vector<ull>(m+1)),ht(n+1,vector<ull>(m+1)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) hs[i][j]=add(mul(hs[i][j-1],bs),s[i][j]),ht[i][j]=add(mul(ht[i][j-1],bs),t[i][j]); bool ok=0; for(int t=0;t<m;t++) { pre.clear(),suf.clear(); Graph::n=n*4; for(int i=0;i<Graph::n;i++) Graph::g[i].clear(); for(int i=1;i<=n;i++) { ull L=geth(hs[i],1,t),R=geth(hs[i],t+1,m); if(!pre.count(L)) pre[L]=pre.size(); if(!suf.count(R)) suf[R]=suf.size(); Graph::g[pre[L]].push_back({suf[R]+n*2,i}); } for(int i=1;i<=n;i++) { ull L=geth(ht[i],1,m-t),R=geth(ht[i],m-t+1,m); if(!suf.count(L)) suf[L]=suf.size(); if(!pre.count(R)) pre[R]=pre.size(); Graph::g[suf[L]+n*2].push_back({pre[R],i+n}); } auto res=Graph::Euler(); if(res.size()!=n*2) continue; vector<int> p,q; for(auto x:res) if(x<=n) p.push_back(x); else q.push_back(x-n); for(int i=0;i<n;i++) cout<<p[i]<<" \n"[i+1==n]; for(int i=0;i<n;i++) cout<<q[i]<<" \n"[i+1==n]; ok=1; break; } if(!ok) cout<<-1<<"\n"; } }
K. Randias Permutation Task
#include<bits/stdc++.h> using namespace std; int n , m; vector<int> p[185] ; vector<int> work(const vector<int> &A,const vector<int>& B) { vector<int> C(A.size()) ; for(int i = 0;i < A.size();i++) C[i] = A[B[i]]; return C; } int main() { // freopen("in.txt","r",stdin) ; ios::sync_with_stdio(false) ; cin.tie(0) ; cin >> n >> m; for(int i = 1;i <= m;i++) { p[i].resize(n) ; for(auto &x : p[i]) {cin >> x; x--;} } set<vector<int> > st ; for(int i = 1;i <= m;i++) { vector<vector<int> > nv ; for(auto &V : st) nv.push_back(work(V , p[i])) ; st.insert(p[i]) ; for(auto &V : nv) st.insert(V) ; } cout << st.size() << '\n' ; return 0; }
L. Alea Iacta Est
#include "bits/stdc++.h" using namespace std; typedef long long ll; #define all(x) (x).begin(),(x).end() const int N=1e6; int mn[N+1],pr[N]; vector<pair<int,int>> getw(int n) { vector<pair<int,int>> w; while (n>1) { int x=mn[n],y=1; n/=x; while (n%x==0) n/=x,++y; w.emplace_back(x,y); } return w; } void multiply(vector<int> &f,int p)//f*(1-x^p)/(1-x) { int n=f.size(),i; for (i=n-p-1; i>=0; i--) f[i+p]-=f[i]; for (i=1; i<n; i++) f[i]+=f[i-1]; } void divide(vector<int> &f,int p)//f/(1-x^p)*(1-x) { int n=f.size(),i; for (i=n-1; i; i--) f[i]-=f[i-1]; for (i=0; i<n-p; i++) f[i+p]+=f[i]; } vector<int> divide(int n,int p1,int p2)//(1-x^n)/((1-x)*Phi_{p1p2}) { assert(n%(p1*p2)==0); int m=p1*p2; int q=n/m,i; vector<int> f(n); for (i=0; i<q; i++) f[i*m]=1; multiply(f,p1); multiply(f,p2); return f; } int main() { ios::sync_with_stdio(0); cin.tie(0); int T; cin>>T; int cnt=0; { int i,j; mn[1]=1; for (i=2; i<=N; i++) { if (!mn[i]) { mn[i]=i; pr[cnt++]=i; } for (j=0; i*pr[j]<=N; j++) { mn[i*pr[j]]=pr[j]; if (i%pr[j]==0) break; } } } while (T--) { auto solve=[&]()->pair<vector<int>,vector<int>> { int n,m,i,j; cin>>n>>m; if (n>m) swap(n,m); auto wn=getw(n),wm=getw(m); for (int d=sqrtl((ll)n*m); d>n; d--) if ((ll)n*m%d==0) { int q=gcd(m,d); //n/p*q,m/q*p int p=(ll)n*q/d; assert(n%p==0); vector<int> a(n,1),b(m,1); a.resize(n+m); divide(a,p); divide(b,q); multiply(a,q); multiply(b,p); return {a,b}; } if (n==1) return {vector(n,2),vector(m,1)}; { if (wm.size()>1&&wm[0].first*wm[1].first<=n) { swap(n,m); swap(wn,wm); } if (wn.size()>1) { int p1=wn[0].first,p2=wn[1].first; auto a=divide(n,p1,p2); int p=p1*p2; vector<int> b(p); for (i=0; i<p2; i++) b[i*p1]=1; divide(b,p2); b.resize(m+p); multiply(b,m); return {a,b}; } } assert(wn.size()==1); for (auto [pn,kn]:wn) for (auto [pm,km]:wm) if (pn==pm&&max(kn,km)>1) { bool flg=0; int p=pn; if (kn>km) { swap(kn,km); swap(n,m); flg=1; } vector<int> a(n*p),b(m); for (i=0; i*p<n; i++) for (j=0; j<p; j++) ++a[(i+j)*p]; for (i=0; i*p*p<m; i++) b[i*p*p]=1; multiply(b,pn); multiply(b,pn); return {a,b}; } if (wm.size()>=2) { int p1=wm[0].first; int p2=wm[1].first; assert(p1*p2==m); vector<int> a(n+m),b(m); for (i=0; i*p2<m; i++) a[i*p2]=1; divide(a,p1); multiply(a,n); if (*min_element(all(a))>=0) { for (i=0; i<p1; i++) for (j=0; j<p2; j++) ++b[i+j]; return {a,b}; } } for (i=n-1; i; i--) if ((ll)n*m%i==0) { ll m1=(ll)n*m/i; int n1=i; if (n1+m1>=n*2+m) break; int p=gcd(n,m1); //n/p*q,m/q*p int q=(ll)m*p/m1; assert(m%q==0); assert(p>q); vector<int> a(n,1),b(m,1); b.resize(m+p); divide(a,p); divide(b,q); multiply(a,q); multiply(b,p); return {a,b}; } return {vector(n,2),vector(m,1)}; }; auto [a,b]=solve(); //assert(!a.size()||*min_element(all(a))>=0); //assert(!b.size()||*min_element(all(b))>=0); int s1=accumulate(all(a),0),s2=accumulate(all(b),0); // if (s1>s2) swap(s1,s2),swap(a,b); int n=a.size(),m=b.size(),i,j; cout<<s1; for (i=0; i<n; i++) while (a[i]--) cout<<' '<<i+1; cout<<'\n'<<s2; for (i=0; i<m; i++) while (b[i]--) cout<<' '<<i+1; cout<<'\n'; } }
M. Flipping Cards
#include<bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); int n; cin>>n; vector<int> a(n+5),b(n+5); for(int i=1;i<=n;i++) { cin>>a[i]>>b[i]; } int hf=n/2+1; auto check=[&](int x) { int cur=0; for(int i=1;i<=n;i++) cur+=(a[i]>=x); int maxx=0,sum=0; for(int i=1;i<=n;i++) { int now=(b[i]>=x)-(a[i]>=x); sum+=now; sum=max(sum,0); maxx=max(maxx,sum); } return cur+maxx>=hf; }; int l=1,r=1e9; while(l<r) { int mid=(l+r+1)/2; if(check(mid))l=mid; else r=mid-1; } cout<<l<<endl; return 0; }