A. Bubbles
Enumerates two points to find the intersection point of the perpendicular bisector and the $x$ axis, and the answer = number of points +1.
Time Complexity $o (n^2\log N) $.
#include <cstdio> #include <algorithm> #include <cmath>using namespace Std;const double Eps=1e-9;int SGN (double x) {if (x<-eps) return-1; if (x>eps) return 1; return 0;} struct p{double x, y; P () {x=y=0;} P (double _x,double _y) {x=_x,y=_y;} P operator+ (P v) {return P (X+V.X,Y+V.Y);} P operator-(P v) {return P (X-V.X,Y-V.Y);} P operator* (double v) {return P (x*v,y*v);} P operator/(double v) {return P (x/v,y/v);} P Rot90 () {return P (-y,x);}} A[2000];d ouble q[1111111];d ouble Cross (P a,p b) {return a.x*b.y-a.y*b.x;} int line_intersection (P a,p b,p p,p q,p&o) {if (!SGN (a.x-b.x) &&!sgn (A.Y-B.Y)) return 0; if (!SGN (p.x-q.x) &&!sgn (P.Y-Q.Y)) return 0; Double U=cross (p-a,q-p), D=cross (b-a,q-p); if (SGN (D) ==0) return 0; o=a+ (b-a) * (U/D); return 1;} int main () {freopen ("bubbles.in", "R", stdin); Freopen ("Bubbles.out", "w", stdout); int n; scanf ("%d", &n); for (int i=1;i<=n;i++) {scanf ("%lf%lf", &a[i].x,&a[i].y); } P A (-100,0), B (100,0); int cnt=0; for (int i=1;i<=n;i++) for (int j=1;j<i;j++) {P t= (A[i]+a[j])/2.0; P V=a[i]-a[j]; V=v.rot90 (); P tmp; if (Line_intersection (t,t+v,a,b,tmp)) {q[++cnt]=tmp.x; }} sort (q+1,q+cnt+1); int Ans=1; for (int i=1;i<=cnt;i++) if (i==1| | SGN (q[i]-q[i-1]) ans++; printf ("%d", ans); return 0;}
B. DROP7
Leave the pit.
C. Eulerian Graphs
Leave the pit.
D. At Least half
Enumerate all prime numbers $p$, find the multiples of all $p$, set $s[i]$ to denote $p$ in the previous $i$ number $\times2$, enumerate $i$, to find the smallest $j$ to meet $s[i]-i\geq s[j]-j$, maintain $s[i]-i$ prefix minimum, Then two points can be found. After finding $j$, the greedy calculation goes to the left to the right to expand how much.
Time Complexity $o (N\log n\log\log N) $.
#include <bits/stdc++.h>using namespace Std;typedef long long ll;typedef pair<int,int>pi;const int maxn= 1000020;int a[maxn];vector<int>v[maxn/10];vector<int>pri;int n;bool isp[Maxn];void getp () {for (int i=2;i <maxn;i++) {if (!isp[i]) {pri.push_back (i);} for (int j=0;j<pri.size (); j + +) {if (I*PRI[J]>=MAXN) break;isp[i*pri[j]]=1;if (i%pri[j]==0) Break;}}} int ans,ansr;int g[maxn],gmx[maxn];void Check (vector<int>&v) {//for (int i=0;i<v.size (); i++) printf ("%d" , V[i]);p UTS (""); for (int i=0;i<v.size (); i++) g[i]=v[i]-2* (i+1); for (int i=0;i<v.size (); i++) gmx[i]=v[i]-1-2* (i ), for (int i=1;i<v.size (); i++) Gmx[i]=max (Gmx[i],gmx[i-1]), for (int i=0;i<v.size (); i++) {int J=lower_bound (GMX), Gmx+v.size (), g[i])-gmx;int has=i-j+1,haslen=v[i]-v[j]+1;//printf ("val=1%d val2=%d\n", v[i-1],j); int rr=i==V.size () -1?n: (v[i+1]-1); int ll=j==0?1: (v[j-1]+1); int tmpans=min (rr-ll+1,has*2); int csr=v[i]+min (tmpans-haslen,rr-v[i]);// printf ("%d%d%d\n", Ll,rr,has,tmpans); if (Tmpans>ans) {ANS=TMPANS;ANSR=CSR;}}} void Solve (VECTOR<INT>&V) {check (V);} int main () {freopen ("halfgcd.in", "R", stdin), Freopen ("Halfgcd.out", "w", stdout), GETP (); scanf ("%d", &n); for (int i =1;i<=n;i++) scanf ("%d", A+i), for (int i=1;i<=n;i++) {int x=a[i];for (int j=0;j<pri.size (); j + +) {if (1ll*pri[j] *pri[j]>x) break;if (X%pri[j]) continue; V[j].push_back (i); while (x%pri[j]==0) x/=pri[j];} if (x>1) V[lower_bound (Pri.begin (), Pri.end (), x)-pri.begin ()].push_back (i);} ans=0,ansr=-1;for (int it=0;it<pri.size (); it++) {if (! V[it].size ()) Continue;solve (V[it]);} if (!ans) {puts ("0 0");} else printf ("%d%d\n", ANSR-ANS+1,ANSR); return 0;}
E. Next Partition in RLE Notation
Only the last few numbers are useful, and the classification discussion constructs.
#include <bits/stdc++.h>using namespace std; typedef long long LL; typedef pair < int, int > pii; typedef pai R < ll, ll > PLL; #define CLR (A, X) memset (A, x, sizeof a) const int maxn = 100005; vector < PLL > G; int n; void get (ll N, ll K, ll Val) {ll tmp1 = (n-k)/(VAL-1); LL TMP2 = (n-k)% (VAL-1); LL Tmp3 = k-tmp1-(tmp2 > 0), if (TMP1) G.push_back (PLL (TMP1, Val)), if (TMP2) G.push_back (PLL (1, TMP2 + 1)); if (Tmp3) G.push_back (PLL (Tmp3, 1));} void Solve () {g.clear (); for (int i = 1; I <= n; + + i) {LL x, y; scanf ("%lld%lld", &x, &y); G.push_back (PLL (x, y));} if (n = = 1 | | n = = 2 && G[0].second-g[1].second = = 1) {printf (" -1\n"); return;} PLL a = g[n-1];-N; G.pop_back ();p ll b = g[n-1]; if (G[n-1].second-a.second > 1) {g[n-1].first--; G[n-1].first) {g.pop_back ();--N;} printf ("%lld%lld%lld%lld\n", A.first, A.second , B.first, B.second); get (A.first * a.second + b.second, A.first + 1, b.second-1);} else {g.pop_back ();--n;p ll C = g[n-1]; G[n-1].first--; if (! G[n-1].first) {g.pop_back ();--N;} Get (A.first * a.second + b.first * b.second + c.second, A.first + b.first + 1, c.second-1);} printf ("%d\n", (int) g.size ())), for (int i = 0; i < g.size (), + + i) {printf ("%lld%lld\n", G[i].first, G[i].second);}} int main () {freopen ("next-partition-rle.in", "R", stdin), Freopen ("Next-partition-rle.out", "w", stdout), while (~SCANF ("%d", &n)) solve (); return 0;}
F. Equation
Leave the pit.
G. "Swap-plus" Puzzle
Obviously there is an optimal sequence of operations, the first line of exchange, in the column exchange, and then the last swap lattice.
The order of Exchange, column exchange, and then greedy exchange can be.
#include <cstdio> #include <algorithm> #include <cmath> #include <string> #include <iostream >using namespace Std;int i,j,a[9][9],b[9],c[9],d[9][9],m,e[100];int ans=~0u>>1,cnt;string q[100];int now; int cal (Int*a,int n) {int t=0; int i,j; static int b[100]; for (i=1;i<=n;i++) b[i]=a[i]; for (i=1;i<=n;i++) {for (j=1;j<=n;j++) if (b[j]==i) {if (i!=j) t++; Swap (b[j],b[i]); Break }} return t;} int Cal2 (int*a,int n) {int t=0; int i,j; static int b[100]; for (i=1;i<=n;i++) b[i]=i; for (i=1;i<=n;i++) {for (j=1;j<=n;j++) if (B[j]==a[i]) {if (i!=j) t++; Swap (b[j],b[i]); Break }} return t;} void Conb (Int*a,char st) {//[1,2,3,4]->a static int b[10]; int i,j; for (i=1;i<=4;i++) b[i]=i; for (i=1;i<=4;i++) {for (j=1;j<=4;j++) if (B[j]==a[i]) {if (i!=j) {string t= ""; T.push_back (b[i]+st-1); T.push_back ('-'); T.push_back (b[j]+st-1); q[++cnt]=t; } Swap (B[j],b[i]); Break }}}void Cond () {//a->[1,2,3,4,...,] static int a[9][9]; int i,j,x,y; for (i=1;i<=4;i++) for (j=1;j<=4;j++) a[i][j]=d[i][j]; for (i=1;i<=4;i++) for (j=1;j<=4;j++) {int now= (i-1) *4+j; if (A[i][j]==now) continue; BOOL flag=0; for (x=1;x<=4;x++) {for (y=1;y<=4;y++) if (a[x][y]==now) {flag=1; Swap (a[x][y],a[i][j]); String t= ""; T.push_back (i+ ' a '-1); T.push_back (j+ ' 0 '); T.push_back ('-'); T.push_back (x+ ' a '-1); T.push_back (y+ ' 0 '); q[++cnt]=t; Break } if (flag) break; }}}int Main () {freopen ("puzzle-swap-plus.in", "R", stdin); Freopen ("Puzzle-swap-plus.out", "w", stdout); for (i=1;i<=4;i++) for (j=1;j<=4;j++) scanf ("%d", &a[i][j]); for (i=1;i<=4;i++) b[i]=i; do{for (i=1;i<=4;i++) c[i]=i; do{Now=cal2 (b,4) +cal2 (c,4); for (i=1;i<=4;i++) for (j=1;j<=4;j++) d[b[i]][c[j]]=a[i][j]; m=0; for (i=1;i<=4; i++) for (j=1;j<=4;j++) e[++m]=d[i][j]; Now+=cal (e,16); if (Now<ans) {ans=now; cnt=0; CONB (b, ' a '); CONB (c, ' 1 '); Cond (); }}while (Next_permutation (c+1,c+4+1)); }while (Next_permutation (b+1,b+4+1)); printf ("%d\n", ans); for (i=1;i<=cnt;i++) cout<<q[i]<<endl; return 0;}
H. Wrong Sieve
Consider the recursive relationship between each round and the previous position.
#include <bits/stdc++.h>using namespace Std;const int maxn=105;typedef long Long ll;typedef pair<int,int>pi ; ll solve (ll x) {for (ll i=1;x>= (i+1); i++) {if (x (i+1) ==0) return-1;x=x-x/(i+1);} return x;} int main () {freopen ("sieve.in", "R", stdin), Freopen ("Sieve.out", "w", stdout), int _;scanf ("%d", &_), while (_--) {LL x ; scanf ("%lld", &x); LL ans=solve (x);p rintf ("%lld\n", ans); return 0;}
I. Space Cat
DP, $f [i][j]$] in section $i$ line, the center of gravity is the minimum cost of $j$, pay attention to the case of non-connectivity.
Time complexity $o (n) $.
#include <bits/stdc++.h>using namespace std; typedef pair < int, int > PII; #define CLR (A, X) memset (A, x, sizeof a) typedef long long ll;const ll inf=1ll<<60;const int N=100010;int n,i,a[n],b[n],c[n];ll f[n][2];inline void up (Ll&x,ll y) {if (x>y) x=y;} int main () {int T; Freopen ("Space-cat.in", "R", stdin), Freopen ("Space-cat.out", "w", stdout); scanf ("%d",& n); for (i=1;i<=n;i++) scanf ("%d", &a[i]), and for (i=1;i<=n;i++) scanf ("%d", &b[i]), C[i]=a[i]-b[i];for (i=2; i<=n;i++) if (b[i]>=a[i-1]| | B[i-1]>=a[i]) return puts ("1"), 0;for (i=1;i<=n;i++) f[i][0]=f[i][1]=inf;f[1][0]=0;for (i=1;i<=n;i++) {if (i >1) {if (A[i-1]<=a[i]) up (f[i][1],f[i-1][1]); if (B[i-1]>=b[i]) up (f[i][0],f[i-1][0]); } for (int. j=0;j<4;j++) {up (f[i][0],f[i][1]+c[i]); Up (F[i][1],f[i][0]+c[i]); }}if (F[n][0]>=inf) f[n][0]=-1;printf ("%lld\n", F[n][0]); return 0;}
J. Tic-Tac-Toe Variation
The first step is to fill in the middle, then there are only two cases, the classification discusses the construction strategy.
#include <bits/stdc++.h>using namespace Std;typedef long long ll;typedef pair<int,int>pi;const int maxn= 1000020;char Mp[4][4];bool getmp () {bool Ret=0;for (int i=0;i<3;i++) {scanf ("%s", Mp[i]), for (int j=0;j<3;j++) {if ( mp[i][j]!= ' x ') Ret=1;}} return ret;} int Idx[3][3]={{0,1,2},{7,-1,3},{6,5,4}};int dx[8],dy[8];int curmp[3][3];int CG (char c) {if (c== '. ') Return 0;if (c== ' x ') return 1;return 2;} void Tran () {for (int. i=0;i<3;i++) {for (int j=0;j<3;j++) {CURMP[I][J]=CG (mp[i][j]);}}} void Pt () {for (int. i=0;i<3;i++) {for (int j=0;j<3;j++) {int c=curmp[i][j];if (!c) Putchar ('. '); if (c==1) Putchar (' x '); if (c==2) putchar (' O ');} Puts ("");} Fflush (stdout);} int getst () {for (int. i=0;i<3;i++) {for (int j=0;j<3;j++) {if (curmp[i][j]==2) {return idx[i][j];}}}} int main () {//freopen ("halfgcd.in", "R", stdin),//freopen ("Halfgcd.out", "w", stdout), for (int i=0;i<3;i++) {for (int) j=0;j<3;j++) {if (i==1&&j==1) continue;dx[idx[i][j]]=i;dy[idx[i][j]]=j;}} while (Getmp ()) {int St;memset (curmp,0,sizeof curmp);(Int. it=0;; it++) {if (it==0) {curmp[1][1]=1;pt (); continue;} if (it==1) {getmp (); Tran (); st=getst (); int nst= (st+2)%8;curmp[dx[nst]][dy[nst]]=1;pt (); continue;} if (it==2) {getmp (); Tran (); if (curmp[dx[(st+6)%8]][dy[(st+6)%8]]!=2) {curmp[dx[(st+6)%8]][dy[(st+6)%8]]=1;pt (); break;} else{curmp[dx[(st+3)%8]][dy[(st+3)%8]]=1;pt ();}} if (it==3) {getmp (); Tran (); int nst=st&1? ( (st+1)%8):((st+4)%8), if (!curmp[dx[nst]][dy[nst]]) {curmp[dx[nst]][dy[nst]]=1;pt (); break;} Else{nst= (st+7)%8;curmp[dx[nst]][dy[nst]]=1;pt (); break;}}} return 0;}
K. Captain Tarjan
For each query, add 1 to the Benquan on the path.
Then the problem becomes, given a tree, find a point, and then randomly split, so that all the weight of the light edge and minimum, two times DP can.
Time Complexity $o (m\log N) $.
#include <bits/stdc++.h>using namespace std; typedef long long LL; typedef pair < int, int > PII; #define CLR (A, X) memset (A, x, sizeof a) const int MAXN = 100005; vectors < PII > G[MAXN]; LL DP[MAXN], DP2[MAXN], MAXC[MAXN]; LL LDP[MAXN], RDP[MAXN], LMAXC[MAXN], RMAXC[MAXN]; int C[MAXN]; int SIZ[MAXN]; int SON[MAXN]; int PRE[MAXN]; int Top[ma XN]; int DEP[MAXN]; int n, M; LL ans; void Predfs (int u, int f) {siz[u] = 1; Son[u] = 0; for (int i = 0; i < g[u].size (); + + i) {int v = g[u ][i].first; if (v = = f) Continue;p re[v] = u;d ep[v] = Dep[u] + 1;p redfs (v, u); siz[u] + = Siz[v]; if (Siz[v] > Siz[son[u]]) son[u] = V;}} void rebuild (int u, int top_element) {Top[u] = top_element; if (Son[u]) rebuild (Son[u], top_element); for (int i = 0; I < g[u].size (); + + i) {int v = g[u][i].first; if (v = pre[u] && v! = Son[u]) rebuild (V, v);}} int Get_lca (int x, int y) {while (top[x]! = Top[y]) {if (Dep[top[x]] &Gt Dep[top[y]]) x = pre[top[x]]; else y = pre[top[y]];} return dep[x] < Dep[y]? X:y;} void dfs1 (int u) {for (int i = 0; i < g[u].size (); + + i) {int v = g[u][i].first; if (v = = Pre[u]) Continue;d FS1 (v); G[u][i].second = C[v]; C[u] + + c[v];}} void dfs2 (int u) {dp[u] = Maxc[u] = 0; for (int i = 0; i < g[u].size (); + + i) {int v = g[u][i].first; if (v = = Pre[u]) Continue;d fs2 (v);DP [u] + = Dp[v] + g[u][i].second; maxc[u] = max (Maxc[u], G[u][i].second + 0LL);} Dp[u]-= Maxc[u];} void Dfs3 (int u, int cost) {int n = g[u].size (); Ldp[0] = 0; Rdp[n-1] = 0; Lmaxc[0] = 0; Rmaxc[n-1] = 0; for (int i = 1; i < n; + + i) {int v = g[u][i-1].first; if (v = = Pre[u]) {ldp[i] = ldp[i-1] ; Lmaxc[i] = lmaxc[i-1];} else {Ldp[i] = Ldp[i-1] + dp[v] + G[u][i-1].second; Lmaxc[i] = max (lmaxc[i-1], G[u][i-1].second + 0LL);}} for (int i = n-2; I >= 0;--i) {int v = g[u][i + 1].first; if (v = = Pre[u]) {Rdp[i] = rdp[i + 1]; RmaXc[i] = rmaxc[i + 1];} else {Rdp[i] = rdp[i + 1] + Dp[v] + g[u][i + 1].second; Rmaxc[i] = max (rmaxc[i + 1], g[u][i + 1].second + 0LL);}} for (int i = 0; i < n; + + i) {int v = g[u][i].first; if (v = = Pre[u]) Continue;DP 2[v] = Dp2[u] + ldp[i] + rdp[i] + Cost-max (max (Lmaxc[i], rmaxc[i]), cost + 0LL); ans = min (ans, dp2[v] + dp[v] + maxc[v] + G[u][i].second- Max (Maxc[v], 0LL + G[u][i].second));} for (int i = 0; i < n; + + i) {int v = g[u][i].first; if (v = = Pre[u]) Continue;d fs3 (V, G[u][i].second);}} void Solve () {for (int i = 1; I <= n; + + i) {g[i].clear (); c[i] = 0;} for (int i = 1; i < n; + + i) {int u, v; scanf ("%d%d", &u, &v); G[u].push_back (PII (V, 0)); G[v].push_back (PII (U, 0));} Predfs (1, 1); Rebuild (1, 1); for (int i = 0; i < m; + + i) {int u, v; scanf ("%d%d", &u, &v); c [u] + +; C[v] + +; int LCA = GET_LCA (U, v); C[lca]-= 2;} Dp2[1] = 0;d fs1 (1);d FS2 (1); aNS = dp[1];d fs3 (1, 0);p rintf ("%lld\n", ans); int main () {freopen ("treepaths.in", "R", stdin), Freopen ("Treepaths.out", "w", stdout), while (~SCANF ("%d%d" , &n, &m)) solve (); return 0;}
L. Gardening Lesson
Find the center of gravity of two trees, weight lifting heart as root, and then find the hash value of each subtrees tree, in two trees together Dfs can.
Time Complexity $o (n\log N) $.
#include <bits/stdc++.h>using namespace Std;typedef long long ll;typedef pair<int,int>pi;const int maxn = 100005, x = 123, M = 998244353, left = all, right = 371; const int Hleaf=left*right,inf=1e9;vector < int > G1[max N], G2[MAXN]; int H1[MAXN], H2[MAXN]; int sz[maxn],sonsz[maxn],ans; void Dfs (int u, vector<int>*g,int p) {sz[u]= 1 ; sonsz[u]=0;for (int i=0;i<g[u].size (); ++i) {int v =g[u][i];if (v==p) Continue;d FS (v,g,u); Sz[u]+=sz[v];if (SZ[V) >sonsz[u]) sonsz[u]=sz[v];}} Vector<int>getroot (vector<int>*g,int N) {dfs (1,g,0); vector<int>ret;for (int i=1;i<=n;++i) {if ( Max (N-sz[i],sonsz[i]) <=n/2) {ret.push_back (i);}} return ret;} BOOL Cmp1 (int a, int b) {return h1[a]
Summarize:
- I found the tree isomorphism template wrong.
XVI Open Cup named after e.v. Pankratiev. GP of SPB