The 2022 ICPC Asia Hangzhou Regional Programming Contest
题解:
https://files.cnblogs.com/files/clrs97/2022ICPCHangzhouTutorial.pdf
Code:
A. Modulo Ruins the Legend
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include<bits/stdc++.h> using namespace std; int n,m; int exgcd( int a, int b, int &x, int &y) { if (!b) { x=1,y=0; return a; } int g=exgcd(b,a%b,y,x); y-=a/b*x; return g; } int main() { scanf ( "%d%d" ,&n,&m); int s=0; for ( int i=1,x;i<=n;i++) { scanf ( "%d" ,&x); s=(s+x)%m; } //an - bm = g int a,b; int t=n%2==1?n:n/2; int g=exgcd(t,m,a,b); //a * n int k=s%g,x=(k-s)/g; x=1ll*x*a%m; if (x<0) x+=m; printf ( "%d\n" ,k); if (n%2==0) { if (x%2==0) printf ( "%d %d\n" ,x/2,0); else printf ( "%d %d\n" ,(((x-1)/2-n/2)%m+m)%m,1%m); } else printf ( "%d %d\n" ,x,0); } |
B. Useful Algorithm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e5+1e3+7; int n,m,q; int c[N],d[N],w[21]; int cnt,rt[21]; struct Tree{ #define ls (x<<1) #define rs (x<<1|1) struct T{ int mx; int v[2]; }; vector<T>t; void update( int x) { t[x].mx=max({t[ls].mx,t[rs].mx,t[ls].v[1]+t[rs].v[0]}); t[x].v[0]=max(t[ls].v[0],t[rs].v[0]); t[x].v[1]=max(t[ls].v[1],t[rs].v[1]); } void build( int x, int l, int r) { if (x==1) t.resize(r*4+1); if (l==r) { t[x].mx=-2e9; t[x].v[0]=t[x].v[1]=-1e9; return ; } int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); update(x); } void change( int x, int p, int a, int b, int l, int r) { if (l==r) { t[x].v[a]=b; t[x].mx=t[x].v[0]+t[x].v[1]; return ; } int mid=(l+r)>>1; if (p<=mid) change(ls,p,a,b,l,mid); else change(rs,p,a,b,mid+1,r); update(x); } #undef ls #undef rs }tr[21]; struct MXH{ priority_queue< int >q,dq; void insert( int x) { q.push(x); } void erase( int x) { dq.push(x); } int top() { while (q.size()&&dq.size()) { if (q.top()==dq.top()) q.pop(),dq.pop(); else break ; } if (q.size()) return q.top(); else return -1e9; } }; vector<MXH>s[21]; int get(MXH &s) { return s.top(); } ll calc() { ll ret=0; for ( int i=1;i<=m;i++) ret=max(ret,1ll*tr[i].t[1].mx*w[i]); return ret; } int main() { ios::sync_with_stdio( false ); cin.tie(0); cin>>n>>m>>q; for ( int i=1;i<=m;i++) cin>>w[i]; for ( int i=1;i<=n;i++) cin>>c[i]; for ( int i=1;i<=n;i++) cin>>d[i]; for ( int i=1;i<=m;i++) s[i].resize(1<<i); for ( int i=1;i<=n;i++) for ( int j=1;j<=m;j++) s[j][c[i]%(1<<j)].insert(d[i]); for ( int i=1;i<=m;i++) { tr[i].build(1,0,1<<i); for ( int j=0;j<(1<<i);j++) { int mx=get(s[i][j]); if (mx<0) continue ; tr[i].change(1,j,0,mx,0,(1<<i)); tr[i].change(1,(1<<i)-j,1,mx,0,(1<<i)); } } ll ans=calc(); cout<<ans<< "\n" ; while (q--) { ll x,u,v; cin>>x>>u>>v; x^=ans,u^=ans,v^=ans; for ( int i=1;i<=m;i++) { int p=c[x]%(1<<i); s[i][p].erase(d[x]); int mx=get(s[i][p]); tr[i].change(1,p,0,mx,0,(1<<i)); tr[i].change(1,(1<<i)-p,1,mx,0,(1<<i)); } c[x]=u; d[x]=v; for ( int i=1;i<=m;i++) { int p=c[x]%(1<<i); s[i][p].insert(d[x]); int mx=get(s[i][p]); tr[i].change(1,p,0,mx,0,(1<<i)); tr[i].change(1,(1<<i)-p,1,mx,0,(1<<i)); } ans=calc(); cout<<ans<< "\n" ; } } |
C. No Bug No Game
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include<cstdio> const int N=3005,M=3005,V=15; int n,m,sum,i,j,k,x,t,sz,full,size[N],w[N][V],f[2][M]; inline void up( int &a, int b){a<b?(a=b):0;} int main(){ scanf ( "%d%d" ,&n,&m); for (i=1;i<=n;i++){ scanf ( "%d" ,&size[i]); sum+=size[i]; for (j=1;j<=size[i];j++) scanf ( "%d" ,&w[i][j]); } if (m>sum)m=sum; for (j=0;j<2;j++) for (k=0;k<=m;k++)f[j][k]=-1; f[0][0]=0; for (i=1;i<=n;i++){ sz=size[i]; full=w[i][size[i]]; for (j=1;~j;j--) for (k=m;~k;k--){ t=f[j][k]; if (t<0) continue ; if (k+sz<=m)up(f[j][k+sz],t+full); if (j) continue ; for (x=0;x<=sz&&k+x<=m;x++)up(f[1][k+x],t+w[i][x]); } } printf ( "%d" ,f[1][m]); } |
D. Money Game
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e5+1e3+7; int n,a[N]; int main() { scanf ( "%d" ,&n); long long s=0; for ( int i=1;i<=n;i++) scanf ( "%d" ,&a[i]),s+=a[i]; for ( int i=1;i<=n;i++) printf ( "%.15lf%c" ,1.0*s*((i==1)+1)/(n+1), " \n" [i==n]); } |
E. Oscar is All You Need
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e3+1e2+7; int T,n; int a[N],b[N],c; typedef pair< int , int > pii; vector<pii>ans; void opt( int x, int y) { assert (x>0&&y>0&&x+y<n); c=0; for ( int i=n-y+1;i<=n;i++) b[++c]=a[i]; for ( int i=x+1;i<=n-y;i++) b[++c]=a[i]; for ( int i=1;i<=x;i++) b[++c]=a[i]; for ( int i=1;i<=n;i++) a[i]=b[i]; ans.push_back({x,y}); } int main() { scanf ( "%d" ,&T); while (T--) { scanf ( "%d" ,&n); for ( int i=1;i<=n;i++) scanf ( "%d" ,&a[i]); ans.clear(); if (n==3) { vector<pii>ans; if (a[1]>a[3]) opt(1,1); } else { if (a[1]!=1) { int pos=1; for ( int i=2;i<=n;i++) if (a[i]==1) pos=i; if (pos==2) { opt(2,1); opt(1,1); } else opt(1,n-pos+1); assert (a[1]==1); } for ( int i=2;i<=n-2;i++) { if (a[i]==i) continue ; int pos=-1; for ( int j=i+1;j<=n;j++) if (a[j]==i) pos=j; assert (pos!=-1); if (pos!=i+1) { opt(i-1,n-pos+2); opt(1,i-1); } else { opt(i-1,1); opt(2,i-1); } } if (a[n-1]==n) { //1, 2, ..., n - 2, n, n - 1 opt(1,1); //n-1 , 2, ..., n - 2, n, 1 opt(n-2,1); //1, n, n-1, 2, ..., n - 2 opt(2,n-3); //2, ..., n-2, n-1, 1, n opt(n-3,1); //n, n-1, 1, 2, ..., n-2 opt(1,n-2); //1, 2, ..., n-2, n-1, n } for ( int i=1;i<=n;i++) assert (a[i]==i); } printf ( "%d\n" ,( int )ans.size()); for ( auto [x,y]:ans) printf ( "%d %d\n" ,x,y); } } |
F. Da Mi Lao Shi Ai Kan De
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include<bits/stdc++.h> #define ll long long using namespace std; int n; map<string, int >mp; int main() { ios_base::sync_with_stdio( false ); int Tcase; cin>>Tcase; while (Tcase--) { int num=0; cin>>n; for ( int i=1;i<=n;i++) { string str; cin>>str; int L=str.size(); int ok=0; for ( int j=0;j+2<L;j++) { if (str[j]== 'b' && str[j+1]== 'i' && str[j+2]== 'e' ) ok=1; } if ( ok && mp.count(str) > 0 ) ok=0; if (ok) { cout<<str<< '\n' ; mp[str]=1; num++; } } if (num==0) { cout<< "Time to play Genshin Impact, Teacher Rice!\n" ; } } return 0; } |
G. Subgraph Isomorphism
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include <bits/stdc++.h> using namespace std; vector< int > G[100005], sta; int n, m; bool vis[100005]; int dfs( int v, int p) { vis[v] = true ; sta.push_back(v); for ( auto u : G[v]) { if (u == p) continue ; if (vis[u]) return u; else { int ret = dfs(u, v); if (ret != -1) return ret; } } sta.pop_back(); return -1; } map<vector< int >, int >MAP; int cnt; int hs[100005]; vector< int >tmp; void gen_hs( int v, int p) { int deg=0; for ( auto u : G[v]) { if (u == p || vis[u]) continue ; gen_hs(u, v); deg++; } tmp.resize(deg); deg=0; for ( auto u : G[v]) { if (u == p || vis[u]) continue ; tmp[deg++]=hs[u]; } sort(tmp.begin(),tmp.end()); int &o=MAP[tmp]; if (!o)o=++cnt; hs[v]=o; } void solve() { scanf ( "%d%d" , &n, &m); for ( int i = 1; i <= n; i++) G[i].clear(); for ( int i = 0; i < m; i++) { int u, v; scanf ( "%d%d" , &u, &v); G[u].push_back(v); G[v].push_back(u); } if (m > n) { printf ( "NO\n" ); return ; } if (m < n) { printf ( "YES\n" ); return ; } for ( int i = 1; i <= n; i++) vis[i] = false ; sta.clear(); int r = dfs(1, 0); for ( int i = 0; i < ( int )sta.size(); i++) if (sta[i] == r) { sta.erase(sta.begin(), sta.begin() + i); break ; } for ( int i = 1; i <= n; i++) vis[i] = false ; for ( auto v : sta) vis[v] = true ; cnt=0; MAP.clear(); for ( auto v : sta) gen_hs(v, 0); for ( int i = 0; i < ( int )sta.size(); i++) if (hs[sta[i]] != hs[sta[(i + 2) % ( int )sta.size()]]) { printf ( "NO\n" ); return ; } printf ( "YES\n" ); } int main() { int T; scanf ( "%d" , &T); while (T --) solve(); return 0; } |
H. RPG Pro League
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | #include<cstdio> #include<algorithm> #include<vector> #include<queue> using namespace std; typedef pair< int , int >P; typedef long long ll; const int N=100005; int n,q,i,j,S,x,y,mask[N],cost[N],pool[N],is[N]; int clim,num,adj[5],cnt[9],bound[257]; ll ans; priority_queue<P>used[9]; priority_queue<P,vector<P>,greater<P> >unused[9]; struct Lim{ int mask,cap;}lim[17]; inline int cmp( int x, int y){ return cost[x]<cost[y];} inline bool check(){ for ( int i=1;i<=clim;i++){ int mask=lim[i].mask,cap=lim[i].cap; for ( int j=1;j<8;j++) if (mask>>j&1){ cap-=cnt[j]; if (cap<=0) break ; } if (cap>0) return 0; } return 1; } inline int getused( int S){ while (!used[S].empty()){ P t=used[S].top(); if (!is[t.second]||cost[t.second]!=t.first){ used[S].pop(); continue ; } return t.second; } return 0; } inline int getunused( int S){ while (!unused[S].empty()){ P t=unused[S].top(); if (is[t.second]||cost[t.second]!=t.first){ unused[S].pop(); continue ; } return t.second; } return 0; } inline void modify( int x, int y){ int S=mask[x],i,best,who=0; if (is[x]){ ans+=y-cost[x]; if (y<=cost[x]){ used[S].push(P(cost[x]=y,x)); return ; } best=cost[x]=y; cnt[S]--; for (i=1;i<8;i++){ y=getunused(i); if (!y) continue ; if (cost[y]>=best) continue ; cnt[mask[y]]++; if (check())best=cost[y],who=y; cnt[mask[y]]--; } if (who){ is[x]=0; unused[S].push(P(cost[x],x)); ans+=best-cost[x]; cnt[mask[who]]++; is[who]=1; used[mask[who]].push(P(cost[who],who)); } else { cnt[S]++; used[S].push(P(cost[x],x)); } } else { if (y>=cost[x]){ unused[S].push(P(cost[x]=y,x)); return ; } best=cost[x]=y; cnt[S]++; for (i=1;i<8;i++){ y=getused(i); if (!y) continue ; if (cost[y]<=best) continue ; cnt[mask[y]]--; if (check())best=cost[y],who=y; cnt[mask[y]]++; } if (who){ is[x]=1; used[S].push(P(cost[x],x)); ans+=cost[x]-best; cnt[mask[who]]--; is[who]=0; unused[mask[who]].push(P(cost[who],who)); } else { cnt[S]--; unused[S].push(P(cost[x],x)); } } } int main(){ scanf ( "%d" ,&n); for (i=1;i<=n;i++){ char s[9]; scanf ( "%s%d" ,s,&cost[i]); for (j=0;s[j];j++){ if (s[j]== 'D' )mask[i]|=1; else if (s[j]== 'S' )mask[i]|=2; else mask[i]|=4; } cnt[mask[i]]++; } for (i=0;i<3;i++) for (j=1;j<8;j++) if (j>>i&1)adj[i]|=1<<j; adj[3]=adj[0]|adj[1]; num=n/4; for (S=1;S<1<<4;S++){ int T=0,sum=0; for (i=0;i<4;i++) if (S>>i&1)T|=adj[i]; for (i=1;i<8;i++) if (T>>i&1)sum+=cnt[i]; int pop=__builtin_popcount(S); num=min(num,sum/pop); bound[T]=max(bound[T],pop); } for (i=1;i<256;i++) if (bound[i]){ lim[++clim].mask=i; lim[clim].cap=num*bound[i]; } for (i=1;i<=n;i++)pool[i]=i; sort(pool+1,pool+n+1,cmp); for (i=n;i;i--){ x=pool[i]; cnt[mask[x]]--; if (!check()){ ans+=cost[x]; is[x]=1; cnt[mask[x]]++; used[mask[x]].push(P(cost[x],x)); } else unused[mask[x]].push(P(cost[x],x)); } scanf ( "%d" ,&q); while (q--) scanf ( "%d%d" ,&x,&y),modify(x,y), printf ( "%lld\n" ,ans); } |
I. Guess Cycle Length
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include<bits/stdc++.h> using namespace std; constexpr int MAGIC_S=3333,MAGIC_B=3333; int main() { ios_base::sync_with_stdio( false ); auto walk=[&]( int x) { cout<< "walk " <<x<<endl; int y; cin>>y; return y; }; mt19937 rng(58); int maxx=0; for ( int i=1;i<=MAGIC_S;i++) { int x=rng()%1000000001; maxx=max(maxx,walk(x)); } map< int , int > mp; for ( int i=MAGIC_B-1;i>=0;i--) { int x=walk(1); if (mp.count(x)) { cout<< "guess " <<mp[x]-i<<endl; return 0; } mp[x]=i; } for ( int i=0;i<MAGIC_B;i++) { int x; if (i==0)x=maxx; else x=MAGIC_B; int y=walk(x); if (mp.count(y)) { cout<< "guess " <<maxx+i*MAGIC_B+mp[y]<<endl; return 0; } } assert (0); return 0; } |
J. Painting
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #include<cstdio> #include<set> #include<algorithm> using namespace std; typedef long long ll; typedef pair< int , int >P; const int N=300005,K=19,inf=1000010; int f[N][K],d[N]; set<P>T; struct E{ int k,b;}e[N]; ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;} struct Frac{ ll up,down; Frac(){} Frac(ll _up,ll _down){ up=_up,down=_down; if (down<0)up*=-1,down*=-1; } void simplify(){ if (!up){down=1; return ;} ll t=gcd(up>0?up:-up,down); up/=t,down/=t; } void show(){ simplify(); printf ( "%lld/%lld" ,up,down); } }; struct Point{ Frac x,y; Point(){} Point(Frac _x,Frac _y){x=_x,y=_y;} void show(){ putchar ( '(' ); x.show(); putchar ( ',' ); y.show(); putchar ( ')' ); } }h[N]; inline Point intersection( const E&A, const E&B){ return Point(Frac(B.b-A.b,A.k-B.k),Frac(1LL*A.k*B.b-1LL*A.b*B.k,A.k-B.k)); //(v/v,v^2/v) } inline int sgn( const E&A, const Point&B){ Frac t(B.x.up*A.k+B.x.down*A.b,B.x.down); //(v^2,v) ll tmp=t.up*B.y.down-t.down*B.y.up; //t.up/t.down-y.up/y.down if (!tmp) return 0; return tmp>0?1:-1; //1 means line A is above point B } inline int lca( int x, int y){ if (d[x]<d[y])swap(x,y); for ( int i=K-1;~i;i--) if (d[f[x][i]]>=d[y])x=f[x][i]; if (x==y) return x; for ( int i=K-1;~i;i--) if (f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; return f[x][0]; } inline int find( const E&e, int x, int top, int t){ for ( int j=K-1;~j;j--){ int o=f[x][j]; if (d[o]<=d[top]) continue ; if (sgn(e,h[o])*t>=0)x=o; } while (x!=top&&sgn(e,h[x])*t>=0)x=f[x][0]; if (x!=top&&sgn(e,h[x])*t<0) return x; return 0; } int main(){ int n,W; scanf ( "%d%d" ,&n,&W); e[n+1].b=0; h[n+1]=Point(Frac(1,1),Frac(0,1)); d[n+1]=1; T.insert(P(0,n+1)); e[n+2].b=0; h[n+2]=Point(Frac(1,1),Frac(inf,1)); d[n+2]=1; T.insert(P(inf,n+2)); for ( int i=1;i<=n;i++){ int A,B,C; scanf ( "%d%d%d" ,&A,&B,&C); e[i].k=B-A; e[i].b=A; set<P>::iterator it=T.lower_bound(P(A,0)); int nxt=it->second; it--; int pre=it->second; if (C)T.insert(P(A,i)); int top=lca(pre,nxt); int fa=find(e[i],pre,top,1); if (!fa)fa=find(e[i],nxt,top,-1); if (!fa)fa=top; d[i]=d[fa]+1; f[i][0]=fa; if (!fa)h[i]=Point(Frac(1,1),Frac(B,1)); else { h[i]=intersection(e[i],e[fa]); if (C) for ( int j=1;j<K;j++)f[i][j]=f[f[i][j-1]][j-1]; } Point ans=h[i]; ans.x.up*=W; ans.show(); puts ( "" ); } } |
K. Master of Both
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1000050; const int maxd=26; int top=0; int son[maxn+50][maxd]; int sz[maxn+50]; int val[maxn+50]; ll cnt[maxd+5][maxd+5]; ll ans2=0; void ins( int x, const string &str, int pos, int len){ sz[x]++; if (pos==len){ val[x]++; ans2+=sz[x]-val[x]; return ; } int now=str[pos]- 'a' ; for ( int i=0;i<maxd;i++) if (i!=now && son[x][i]!=-1) cnt[now][i]+=sz[son[x][i]]; int & nxt=son[x][now]; if (nxt==-1) nxt=++top; ins(nxt,str,pos+1,len); } int n,Q; string str; int main(){ ios_base::sync_with_stdio( false ); memset (son,-1, sizeof (son)); cin >> n >> Q; for ( int i=1;i<=n;i++){ cin >> str; ins(0,str,0,str.length()); } for (;Q--;){ cin >> str; int len=str.length(); ll ans=ans2; for ( int i=0;i<len;i++) for ( int j=i+1;j<len;j++) ans+=cnt[str[i]- 'a' ][str[j]- 'a' ]; cout << ans << "\n" ; } return 0; } |
L. Levenshtein Distance
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=200010,K=35; int k,n,m,cnt,i,j,x,y,z,Log[N<<1],f[K][K<<1],g[N],ans[K]; char a[N],b[N],s[N<<2]; namespace SA{ int n,rk[N<<2],sa[N<<2],h[N<<2],tmp[N<<2],cnt[N<<2],f[18][N<<1]; void suffixarray( int n, int m){ int i,j,k;n++; for (i=0;i<n;i++)cnt[rk[i]=s[i]]++; for (i=1;i<m;i++)cnt[i]+=cnt[i-1]; for (i=0;i<n;i++)sa[--cnt[rk[i]]]=i; for (k=1;k<=n;k<<=1){ for (i=0;i<n;i++){ j=sa[i]-k; if (j<0)j+=n; tmp[cnt[rk[j]]++]=j; } sa[tmp[cnt[0]=0]]=j=0; for (i=1;i<n;i++){ if (rk[tmp[i]]!=rk[tmp[i-1]]||rk[tmp[i]+k]!=rk[tmp[i-1]+k])cnt[++j]=i; sa[tmp[i]]=j; } memcpy (rk,sa,n* sizeof ( int )); memcpy (sa,tmp,n* sizeof ( int )); if (j>=n-1) break ; } n--; for (j=rk[h[i=k=0]=0];i<n;i++,k++) while (~k&&s[i]!=s[sa[j-1]+k])h[j]=k--,j=rk[sa[j]+1]; for (i=1;i<=n;i++)f[0][i]=h[i]; for (j=1;(1<<j)<=n;j++) for (i=1;i+(1<<j)-1<=n;i++)f[j][i]=min(f[j-1][i],f[j-1][i+(1<<(j-1))]); } inline int ask( int x, int y){ x=rk[x],y=rk[y]; if (x>y)swap(x,y); int k=Log[y-x]; return min(f[k][x+1],f[k][y-(1<<k)+1]); } } inline int lcp( int x, int y){ if (x>n||y>m) return 0; return SA::ask(x-1,y+n); } inline void umax( int &a, int b){a<b?(a=b):0;} inline void umin( int &a, int b){a>b?(a=b):0;} int main(){ scanf ( "%d%s%s" ,&k,b+1,a+1); n= strlen (a+1),m= strlen (b+1); for (i=1;i<=n;i++)s[cnt++]=a[i]; s[cnt++]= '#' ; for (i=1;i<=m;i++)s[cnt++]=b[i]; for (i=2;i<=cnt;i++)Log[i]=Log[i>>1]+1; SA::suffixarray(cnt,256); for (i=1;i<=n;i++){ if (n-i+1<m-k) break ; for (j=m-k;j<=m+k;j++){ x=i+j-1; if (x>=i&&x<=n)g[x]=N; } for (j=0;j<=k;j++) for (x=-k;x<=k;x++)f[j][x+K]=0; f[0][K]=i; for (j=0;j<=k;j++) for (x=-k;x<=k;x++){ y=f[j][x+K]; if (!y) continue ; z=y-i+x+1; y+=lcp(y,z); z=y-i+x+1; if (z>m)umin(g[y-1],j); if (j<k){ if (y<=n&&z<=m)umax(f[j+1][x+K],y+1); if (y<=n)umax(f[j+1][x+K-1],y+1); if (z<=m)umax(f[j+1][x+K+1],y); } } for (j=m+k;j>=m-k;j--){ x=i+j-1; if (x>=i&&x<=n){ if (x<n&&j<m+k)umin(g[x],g[x+1]+1); if (g[x]<=k)ans[g[x]]++; } } } for (i=0;i<=k;i++) printf ( "%d\n" ,ans[i]); } |
M. Please Save Pigeland
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #include<bits/stdc++.h> using namespace std; using pii=pair< int , int >; using ll= long long ; const int N=5e5+1e3+7; int n,k,c[N],key[N]; vector<pii>g[N]; struct Data{ ll a,g; }; Data operator +( const Data &a, const Data &b) { if (b.a==-1) return a; if (a.a==-1) return b; return {a.a,__gcd(__gcd(a.g,b.g), abs (a.a-b.a))}; } Data operator +( const Data &a,ll b) { if (a.a==-1) return a; return {a.a+b,a.g}; } int sz[N]; ll d[N]; Data f[N]; void dfs( int x, int F) { f[x].a=-1; sz[x]=key[x]; for ( auto [v,w]:g[x]) { if (v==F) continue ; dfs(v,x); d[x]+=d[v]+1ll*w*sz[v]; sz[x]+=sz[v]; f[x]=f[x]+(f[v]+w); } if (key[x]) f[x]=f[x]+Data({0,0}); } ll ans; void go( int x, int F,Data G,ll D) { Data tG=G+f[x]; ll tD=D+d[x]; ll rG=__gcd(tG.a,tG.g); if (rG) ans=min(ans,tD/rG); else ans=min(ans,tD); // cout<<x<<" "<<tD<<endl; vector<Data>pf,sf; pf.push_back({-1,0}); for ( int i=0;i<g[x].size();i++) { auto [v,w]=g[x][i]; if (v==F) continue ; pf.push_back(pf.back()+(f[v]+w)); } sf.resize(pf.size()+1); sf.back()={-1,0}; int t=( int )sf.size()-2; for ( int i=( int )g[x].size()-1;i>=0;i--) { auto [v,w]=g[x][i]; if (v==F) continue ; sf[t]=sf[t+1]+(f[v]+w); t--; } t=0; for ( int i=0;i<g[x].size();i++) { auto [v,w]=g[x][i]; if (v==F) continue ; ++t; ll nD=D+d[x]-d[v]-1ll*sz[v]*w+1ll*(k-sz[v])*w; Data nG=(pf[t-1]+sf[t+1]+G)+w; if (key[x]) nG=(nG+Data{w,0}); go(v,x,nG,nD); } } int main() { scanf ( "%d%d" ,&n,&k); for ( int i=1;i<=k;i++) scanf ( "%d" ,&c[i]),key[c[i]]=1; for ( int i=1;i<n;i++) { int u,v,w; scanf ( "%d%d%d" ,&u,&v,&w); g[u].push_back({v,w}); g[v].push_back({u,w}); } ans=3e18; dfs(1,0); go(1,0,{-1,0},0); printf ( "%lld\n" ,ans*2); } /* 5 3 3 4 5 1 2 2 2 3 4 2 5 4 3 4 6 */ |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
2016-10-05 XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
2015-10-05 BZOJ3836 : [Poi2014]Tourism