题解:
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; }
- Guilin Programming Collegiate Universal Contestguilin programming collegiate universal programming collegiate contest guilin programming collegiate provincial contest programming collegiate jiangsu contest international programming collegiate contest programming collegiate mianyang contest programming collegiate shenzhen contest programming collegiate shanghai contest programming collegiate contest harbin programming collegiate codeforces contest