The final statistical scores of data structure courses offered in university classrooms are generally composed of "offline homework, offline experimental report, machine test and final theoretical examination". The theoretical knowledge of data structure and corresponding experimental reports have been shared with you before. For details, please click the link below:
Promise Xiaoxu, don't blindly study data structure ~ here's a summary for you!
Teach you to write eight data structure experiment reports (code & Graphics & rich content! Unique!)
Today, the blogger will share with you the AC of the past computer test_ Code for your reference after the test. But seriously, the code style was really not very good at that time! Moreover, because there was no timely record at that time, only the following "broken codes" were left. There was no AC code, and the blogger would mark it [if you remember, hhh], but it was a pity that the corresponding question plane could not be attached (the school had no right to limit it after each computer test... It was also my fault, but I was lazy after the test, QAQ, and there was no screenshot)
Oh, yes! At that time, the teacher asked me to do the star question, so it was not comprehensive
The first time (March 18, 2020)
Question 1
#include<bits/stdc++.h> using namespace std; int a[101][101]; bool vis[101][101]; int point[][3]={{-2,1},{-2,-1},{-2,2},{-2,-2},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1},{2,-2},{2,2}}; struct node {int x,y,bu;} q[10100]; void bfs(int x00,int y00) { int gx,gy,i,head=1,tail=1; memset(vis,0,sizeof(vis)); q[tail].x=x00; q[tail].y=y00; q[tail].bu=0; tail++; vis[x00][y00]=1; while(head<tail) { int x=q[head].x,y=q[head].y, bu=q[head].bu; if(x==1&&y==1) {cout<<bu<<endl; break;} for(i=0; i<12; i++) { gx=x+point[i][0]; gy=y+point[i][1]; if(gx>=1&&gx<=100&&gy>=1&&gy<=100&&vis[gx][gy]==0) { vis[gx][gy]=1; q[tail].x=gx; q[tail].y=gy; q[tail].bu=bu+1; tail++; } } head++; } } int main() { int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2; bfs(x1,y1); bfs(x2,y2); return 0; }
Question 3
#include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> #include<malloc.h> #define ll long long #define maxn 1e9 /*xiaxv It's a chicken with vegetables*/ int top[22]; int time[22]; int df[22][202],m,qwq; float k=0; int xm(int a,int b) { int i=0; for(i=0;i<m;i++) if(time[i]+df[i][top[i]]<=a) {time[i]=0; return i;} int min=999999,t=0; for(i=0;i<m;i++) { if((time[i]+df[i][top[i]]-a)<min) { min=time[i]+df[i][top[i]]-a; t=i; } } time[t]=min; k+=min; return t; } void hll(int a,int b) { int k,t=xm(a,b); top[t]++; df[t][top[t]]=a+b; } int main() { int a,b,i,j; while(~scanf("%d",&m)) { scanf("%d",&qwq); for(i=0; i<qwq; i++) { scanf("%d %d",&a,&b); hll(a,b); } printf("%1.2f\n",k/qwq); memset(time,0,sizeof(time)); memset(top,0,sizeof(top)); k=0; } return 0; }
Question 5 (brackets match)
#include<bits/stdc++.h> #define ll long long #define maxn 1e5 using namespace std; char s[1000]; int a[100],t1=0,t2=0,j=1; int qwq(char s[]) { int i=0; while(i<strlen(s)) { if(s[i]=='[') {a[++t2]=1; t1++;} if(s[i]=='(') {a[++t2]=2; t1++;} if(s[i]==']') { if(a[t2]==1) {t1--; t2--;} else return 0; } if(s[i]==')') { if(a[t2]==2) {t1--; t2--;} else return 0; } ++i; } if(t1==0) return 1; else return 0; } int main() { cin>>s; if(qwq(s))cout<<"OK"; else cout<<"Wrong"; return 0; }
The second time (April 1, 2020)
Question 1
#include <bits/stdc++.h> using namespace std; string s1,s2; void qwq(int a1,int b1,int a2,int b2) { int i,j,k; for(i=a2; i<=b2; i++) { k=0; for(j=a1; j<=b1; j++) if(s2[i]==s1[j]) {k=1; cout<<s1[j]; break;} if(k) break; } if(j>a1) qwq(a1,j-1,1,b2); if(j<b1) qwq(j+1,b1,1,b2); } int main() { cin>>s1>>s2; qwq(0,s1.length()-1,0,s2.length()-1); return 0; }
Question 7
#include <bits/stdc++.h> #define ll long long using namespace std; int n,m,i,j,x,y,rt,mr,sum,Maxx,q[120]={0}; int main() { cin>>n>>m; for(i=1;i<=m;i++) cin>>x>>y,q[y]=x; for(i=1;i<=n;i++) if(q[i]==0) {rt=i; break;} for(i=1;i<=n;i++) { sum=0; for(j=1;j<=n;j++) if(q[j]==i) sum++; if(sum>Maxx) {Maxx=sum; mr=i;} } cout<<rt<<endl<<mr<<endl; for(i=1;i<=n;i++) if(q[i]==mr) cout<<i<<" "; return 0; }
Question 10
#include <bits/stdc++.h> using namespace std; vector<char> pre,in,post; map<int,char> Map; int q[188],i,p; void QWQ(int l,int r,int k) { if(l>=r) {q[k/2]=1; return;} int m=distance(in.begin(),find(in.begin(),in.end(),pre[i++])); Map[k]=in[m]; QWQ(l,m,k*2); QWQ(m+1,r,k*2+1); p=max(p,k); } int hhh(int k) { if(k>p) return 0; if(q[k]) return q[k]; return q[k]=hhh(2*k)+hhh(2*k+1); } void print(int k) { if(!q[k]) return ; for(int j=1; j<=q[k]; j++) cout<<Map[k]; cout<<endl; print(2*k); print(2*k+1); } int main() { int i; string s1,s2; cin>>s1>>s2; for(i=0;i<s1.size();i++) pre.push_back(s1[i]); for(i=0;i<s2.size();i++) in.push_back(s2[i]); QWQ(0,s1.size(),1); for(i=0; i<s1.size(); i++) hhh(1); print(1); cout<<endl; }
Question 11
#include <bits/stdc++.h> #define ll long long using namespace std; typedef struct node; typedef node *tree; struct node { char data; bool check; tree lchild,rchild; }; tree root; char c; int x; ll num,I,answeer,i; void qwq(tree &bt,int sum,int number) { if(sum>x) return; bt=new node; bt->data=number; bt->check=false; qwq(bt->lchild,sum+1,number*2); qwq(bt->rchild,sum+1,number*2+1); } int fgh(int depth,tree &bt) { if(depth==x) return bt->data; if(bt->check) {bt->check=false; fgh(depth+1,bt->rchild);} else {bt->check=true; fgh(depth+1,bt->lchild);} } int main() { cin>>x>>I; qwq(root,1,1); for(i=1;i<=I;i++) answeer=fgh(1,root); cout<<answeer; return 0; }
The third time (April 15, 2020)
Question 6
#include<bits/stdc++.h> #define fish first #define lake second using namespace std; priority_queue<pair<int,int> >heap; int f[105],t[105],d[105]; int main() { int n,m; cin>>n; for(int i=1; i<=n; i++) cin>>f[i]; for(int i=1; i<=n; i++) cin>>d[i]; for(int i=1; i<n; i++) cin>>t[i]; cin>>m; int T=0,t1=0,ans=0,maxn=0; for(int k=1; k<=n; k++) { T=m-t1; ans=0; while(!heap.empty()) {heap.pop();} for(int i=1; i<=k; i++) heap.push(make_pair(f[i],i)); while(T>0 && heap.top().fish>0) { pair<int ,int >a=heap.top(); heap.pop(); ans+=a.fish; a.fish-=d[a.lake]; heap.push(a); T--; } if(ans>maxn) maxn=ans; t1+=t[k]; } cout<<maxn<<endl; return 0; }
Question 7
#include <bits/stdc++.h> #define ll long long using namespace std; const int M=305,N=(1<<8)+1; int a[M],to[N]; ll w[N],dp[M][M][N],g[3]; const ll inf=-1e9; ll ans = inf; int main() { int n,k,i,s,L,mid; cin>>n>>k; for(i=1; i<=n; i++) scanf("%1d",&a[i]); for(s=0; s<(1<<k); s++) scanf("%d%lld",&to[s],&w[s]); memset(dp,0x8f,sizeof(dp)); for(i=1;i<=n;i++) dp[i][i][a[i]]=0; for(L=2;L<=n;L++) for(i=1;i<=n-L+1;i++) { int j=i+L-1,len=j-i; while(len>k-1) len-=(k-1); for(mid=j; mid>0; mid-=k-1) { for(s=0; s<(1<<len); s++) if(dp[i][mid - 1][s] > inf) { if(dp[mid][j][1]>inf) dp[i][j][s<<1|1]=max(dp[i][j][s<<1|1],dp[i][mid-1][s]+dp[mid][j][1]); if(dp[mid][j][0] > inf) dp[i][j][s<<1] = max(dp[i][j][s<<1], dp[i][mid - 1][s] + dp[mid][j][0]); } } if(len==k-1) { g[0]=g[1]=inf; for(s=0; s<(1<<k); s++) if(dp[i][j][s]>inf) g[to[s]] = max(g[to[s]], dp[i][j][s] + w[s]); dp[i][j][1] = g[1]; dp[i][j][0] = g[0]; } } for(s=0; s<(1<<k); s++) ans = max(ans, dp[1][n][s]); cout<<ans; }
Question 10
#include <bits/stdc++.h> #define ll long long using namespace std; struct node { int meg; ll c; node() {meg=0; c=0;} friend bool operator<(node n1,node n2) { if(n1.c!=n2.c) return n1.c>n2.c; return n1.meg>n2.meg; } }; priority_queue<node> q; int n,k,i; ll w[210000]; node cnt[15]; int main() { cin>>n>>k; for(i=1;i<=n;i++) scanf("%lld",&w[i]); while((n-1)%(k-1)) w[++n]=0; for(i=1;i<=n;i++) {node tmp;tmp.c=w[i]; tmp.meg=0; q.push(tmp);} ll ans=0; while(q.size()!=1) { for(i=1;i<=k;i++) cnt[i]=q.top(),q.pop(); node tmp; tmp.meg=0; tmp.c=0; for(i=1;i<=k;i++) tmp.c+=cnt[i].c,tmp.meg=max(tmp.meg,cnt[i].meg); tmp.meg++; ans+=tmp.c; q.push(tmp); } node tmp=q.top(); cout<<ans<<endl<<tmp.meg<<endl; return 0; }
Question 11
#include <bits/stdc++.h> #define N 7000005 using namespace std; int n,m,q,u,v,t; bool cmp(const int &a,const int &b) { return a>b; } priority_queue<int>ans; int cut1[N],cut2[N],now[N]; int sum,h0,h1,h,t0,t1,t2; double p; int main() { scanf("%d %d %d %d %d %d",&n,&m,&q,&u,&v,&t); p=(double)u/v; int tmp; for(t0=1; t0<=n; t0++) scanf("%d",&now[t0]); t0--; t1=t2=0; h0=h1=h2=1; sort(now+1,now+t0+1,cmp); int top; for(int i=1; i<=m; i++) { if(h0>t0) { if(cut1[h1]>cut2[h2]) top=cut1[h1++]; else top=cut2[h2++]; } else if(now[h0]>=cut1[h1] && now[h0]>=cut2[h2]) top=now[h0],h0++; else if(cut1[h1]>=cut2[h2] && now[h0]<=cut1[h1]) top=cut1[h1],h1++; else top=cut2[h2],h2++; top+=sum; int a1=floor(p*(double)top),a2=top-a1; sum+=q; a1-=sum,a2-=sum; cut1[++t1]=a1,cut2[++t2]=a2; if(i%t==0) printf("%d ",top); } putchar('\n'); for(int i=h0; i<=t0; i++) ans.push(now[i]); for(int i=h1; i<=t1; i++) ans.push(cut1[i]); for(int i=h2; i<=t2; i++) ans.push(cut2[i]); for(int i=1; ans.size(); i++) { if(i%t==0) printf("%d ",ans.top()+sum); ans.pop(); } return 0; }
Fourth time
3. Minimum bottleneck enhanced version
#include <bits/stdc++.h> const int MAXN=1e6+10, mod=1e9+7; using namespace std; inline int read() { char c=getchar(); int x=0, f=1; while (c<'0' || c>'9') { if(c=='-') f=-1; c=getchar(); } while (c>='0' && c<='9') x=x*10+c-'0', c=getchar(); return x*f; } int N,M,fa[MAXN],tot,val[MAXN],id[MAXN][21],num,dfn[MAXN],dep[MAXN],lg2[MAXN]; struct Edge { int u, v, w; bool operator<(const Edge &rhs) const { return w < rhs.w; } } E[MAXN]; vector<int> v[MAXN]; int find(int x) {return fa[x]==x?fa[x]:fa[x]=find(fa[x]);} void Kruskal() { for (int i=1; i<=2*N; i++) fa[i]=i; tot = N; for(int i=1; i<=M; i++) { int x = find(E[i].u), y = find(E[i].v); if(x==y) continue; val[++tot] = E[i].w; v[tot].push_back(x); v[tot].push_back(y); v[x].push_back(tot); v[y].push_back(tot); fa[x] = tot; fa[y] = tot; } } void dfs(int x, int fa) { dfn[x] = ++num; dep[x] = dep[fa]+1; id[num][0] = x; for (int i=0, to; i<v[x].size(); i++) { if((to=v[x][i])==fa) continue; dfs(to, x); id[++num][0] = x; } } void RMQ() { for(int i=2; i<=num; i++) lg2[i] = lg2[i>>1] + 1; for(int j=1; j<=20; j++) for(int i=1; i+(1<<j)-1<=num; i++) { int r = i+(1<<(j-1)); id[i][j] = (dep[id[i][j-1]] < dep[id[r][j-1]]) ? id[i][j-1] : id[r][j-1]; } } int A, B, C, P; inline int rnd() { return A = (A*B+C) % P; } int LCA(int x, int y) { x = dfn[x]; y = dfn[y]; if (x > y) swap(x, y); int k = lg2[y - x + 1]; return dep[id[x][k]] < dep[id[y - (1 << k) + 1][k]] ? id[x][k] : id[y - (1 << k) + 1][k]; } int main() { N = read(); M = read(); for (int i = 1; i <= M; i++) { int x = read(), y = read(), z = read(); E[i] = (Edge){ x, y, z }; } sort(E + 1, E + M + 1); Kruskal(); dfs(tot, 0); RMQ(); int ans = 0, Q = read(); A = read(); B = read(); C = read(); P = read(); while (Q--) { int u = rnd() % N + 1, v = rnd() % N + 1; (ans += val[LCA(u, v)]) %= mod; } printf("%d", ans); return 0; }
10. Minimum spanning tree count
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=101; const int M=1010; const int p=31011; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct node{ int u,v,w; }e[M]; struct range{ int l,r; }a[M]; int fa[N],t[M],n,m,k,sum; inline bool cmp(node a,node b){ return a.w<b.w; } int find(int x){ if(fa[x]==x)return x; return find(fa[x]); } inline void unionn(int x,int y){ fa[x]=y; } inline void destory(int x,int y){ fa[x]=x;fa[y]=y; } void dfs(int l,int r,int d,int w){ if(l>r){ if(d==t[w])sum=(sum+1)%p; return; } if(r-l+1+d<t[w])return; int u=find(e[l].u),v=find(e[l].v); if(u!=v&&d<t[w]){ unionn(u,v); dfs(l+1,r,d+1,w); destory(u,v); } dfs(l+1,r,d,w); } int main() { n=read(),m=read(); for(int i=1;i<=m;i++){ e[i].u=read(),e[i].v=read(),e[i].w=read(); } sort(e+1,e+m+1,cmp); for(int i=1;i<=n;i++)fa[i]=i; int cnt=0; for(int i=1;i<=m;i++) { if(e[i].w!=e[i-1].w) { a[++k].l=i; a[k-1].r=i-1; } int u=e[i].u,v=e[i].v; u=find(u),v=find(v); if(u!=v)t[k]++,cnt++,unionn(u,v); } a[k].r=m; if(cnt!=n-1) { puts("0"); return 0; } int ans=1; for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=k;i++) { if(!t[i]) continue; sum=0; dfs(a[i].l,a[i].r,0,i); ans=(ll)ans*sum%p; for(int j=a[i].l;j<=a[i].r;j++) { int u=e[j].u,v=e[j].v; u=find(u),v=find(v); if(u!=v)unionn(u,v); } } printf("%d\n",ans); return 0; }
11. Cooking
#include <bits/stdc++.h> #define ll long long #define ls p<<1 #define rs p<<1|1 using namespace std; const int mxn=2e5+5; int n,m,cnt,hd[mxn]; inline int read() { char c=getchar(); int x=0,f=1; while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();} return x*f; } inline void chkmax(int &x,int y) {if(x<y) x=y;} inline void chkmin(int &x,int y) {if(x>y) x=y;} struct ed { int to,nxt; }t[mxn<<1]; inline void add(int u,int v) { t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt; } int tot,in[mxn],ans[mxn],vis[mxn]; struct Node { int x,y; friend bool operator < (Node a,Node b) { if(a.y==b.y) return a.x>b.x; return a.y>b.y; } }nod[mxn]; int dfs(int u) { int mi=u; for(int i=hd[u];i;i=t[i].nxt) { int v=t[i].to; chkmin(mi,dfs(v)); } nod[u].x=u,nod[u].y=mi; return mi; } priority_queue<int> q; int main() { int T; T=read(); while(T--) { memset(hd,0,sizeof(hd)); memset(in,0,sizeof(in)); memset(vis,0,sizeof(vis)); tot=cnt=0; n=read(); m=read(); int u,v,flag=0; for(int i=1;i<=m;++i) { u=read(); v=read(); add(v,u); ++in[u]; } for(int i=1;i<=n;++i) if(in[i]==0) q.push(i); while(!q.empty()) { u=q.top(); q.pop(); vis[u]=1; ans[++tot]=u; for(int i=hd[u];i;i=t[i].nxt) { v=t[i].to; --in[v]; if(in[v]==0) q.push(v); } } for(int i=1;i<=n;++i) if(!vis[i]) {puts("Impossible!");flag=1;break ;} if(flag) continue ; for(int i=n;i>=1;--i) printf("%d ",ans[i]); printf("\n"); } return 0; }
13. Cake
#include<bits/stdc++.h> using namespace std; unsigned long long t,n,r,h; bool vis[1005],jude; struct node{ double x,y,z; }hole[10005]; bool pd(node a,node b) { long long d; d=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z); if(d<=4*r*r) return true; else return false; } void dfs(int i) { if(jude)return ; if(hole[i].z+r>=h) { jude=1; return ; } for(int j=1;j<=n;j++) { if(pd(hole[i],hole[j])&&!vis[j]) { vis[j]=1; dfs(j); } } } int main() { scanf("%d",&t); for(int i=1;i<=t;i++) { scanf("%d%d%d",&n,&h,&r); memset(vis,0,sizeof(vis));jude=0; for(int j=1;j<=n;j++) scanf("%lf%lf%lf",&hole[j].x,&hole[j].y,&hole[j].z); for(int k=1;k<=n;k++) if(hole[k].z<=r) { vis[k]=1; dfs(k); } if(jude)printf("Yes\n"); else printf("No\n"); } }
Fifth time
7. Euler circuit
#include<bits/stdc++.h> using namespace std; const int N=100010; const int M=1000010; bool flag[M]; int in[N],out[N]; int type,n,m,tot=1,x,y; int head[N],ver[M],nxt[M]; vector<int> ans; void add(int u,int v) { ver[++tot]=v; nxt[tot]=head[u]; head[u]=tot; } void dfs(int x) { for(int &i=head[x],y; y=ver[i],i; i=nxt[i]) { int c=(type==1?i/2:i-1); int sig=i%2; if(flag[c]) continue; flag[c]=1; dfs(y); if(type==1) ans.push_back(sig?-c:c); else ans.push_back(c); } } int main () { scanf("%d%d%d",&type,&n,&m); for(int i=1; i<=m; i++) { scanf("%d%d",&x,&y); add(x,y); if(type==1) add(y,x); out[x]++; in[y]++; } if(type==1) { for(int i=1; i<=n; i++) if((in[i]+out[i])%2) { printf("NO\n"); return 0; } } else{ for(int i=1; i<=n; i++) { if(in[i]!=out[i]) { printf("NO\n"); return 0; } } } for(int i=1; i<=n; i++) if(head[i]) {dfs(i); break;} if(ans.size()!=m) {cout<<"NO"<<endl; return 0;} cout<<"YES"<<endl; for(int i=m-1;i>=0;i--) cout<<ans[i]<<" "; cout<<endl; return 0; }
11. Logistics transportation (shortest circuit and DP)
Idea: this problem combines the shortest path and DP, in which the shortest route is completed by SPFA,
The graph is stored by the adjacency matrix. Use t[i][j] to represent day I to day j. The shortest circuit from the beginning to the end. f[i] minimum cost to store to day I. You can easily get f[i] = min{f[i], f[j]+k+t[j+1][i]*(i-j)}. Output the solution of f[n].
#include<bits/stdc++.h> #define ll long long using namespace std; struct data{ //Side length of adjacency matrix int next,to,w; }e[801]; int ne,head[21]; //Pseudo head node of head adjacency matrix int n,m,k; bool flag[101][21]; //Whether the j (0 < j < = m) wharf is scrapped on the i (0 < i < = n) day ll t[101][101],f[101]; //The t array stores the shortest path from the starting point to the end point from day i (0 < i < = n) to day J (0 < J < = n); void insert(int u,int v,int w){ //Add new edge ne++; e[ne].to=v; e[ne].w=w; e[ne].next=head[u]; head[u]=ne; } int spfa(int a,int b){ bool block[21]; int dis[21],q[500],inq[21]; memset(block,0,sizeof block); memset(dis,127,sizeof dis); memset(inq,0,sizeof inq); for(int i=a;i<=b;i++) for(int j=1;j<=m;j++) if(flag[i][j]) block[j]=1; //Is the j node scrapped between days a and b q[0]=1; //queue inq[1]=1; //Mark whether the node is queued dis[1]=0; int t=0,w=1; //Team leader and tail while(t<w) //SPFA { int p=head[q[t]]; while(p) { if(!block[e[p].to]&&dis[e[p].to]>dis[q[t]]+e[p].w) { dis[e[p].to]=dis[q[t]]+e[p].w; if(!inq[e[p].to]){ q[w++]=e[p].to; inq[e[p].to]=1; } } p=e[p].next; } inq[q[t]]=0; t++; }return dis[m]; } void dp(){ for(int i=1;i<=n;i++){ f[i]=(ll)t[1][i]*i; for(int j=0;j<i;j++) f[i]=min(f[i],f[j]+k+t[j+1][i]*(i-j)); } } int main() { int q; cin>>n>>m>>k>>q; for(int i=1;i<=q;i++) {//Add edge int x,y,z; cin>>x>>y>>z; insert(x,y,z); insert(y,x,z); } int d; cin>>d; for(int i=1;i<=d;i++){ //Record scrap node int x,y,z; cin>>x>>y>>z; for(int j=y;j<=z;j++) flag[j][x]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) t[i][j]=spfa(i,j); dp(); cout<<f[n]<<endl; return 0; }
12. Visit the park (dfs, dijkstra)
#include<bits/stdc++.h> const int K=55,N=100005,M=500005; using namespace std; int n,m,k,p,t1,t2,flag; int d[N],f[N][K],vis[N][K]; int first[N],v[M],w[M],nxt[M]; int First[N],V[M],W[M],Nxt[M]; priority_queue<pair<int,int> >q; void add(int x,int y,int z){ nxt[++t1]=first[x]; first[x]=t1; v[t1]=y; w[t1]=z; } void Add(int x,int y,int z){ Nxt[++t2]=First[x]; First[x]=t2; V[t2]=y; W[t2]=z; } void init() { t1=t2=flag=0; memset(f,-1,sizeof(f)); memset(first,0,sizeof(first)); memset(First,0,sizeof(First)); } void dijkstra(int s) { int x,y,i; memset(d,127/3,sizeof(d)); q.push(make_pair(0,s));d[s]=0; while(!q.empty()) { x=q.top().second;q.pop(); for(i=first[x];i;i=nxt[i]) { y=v[i]; if(d[y]>d[x]+w[i]) { d[y]=d[x]+w[i]; q.push(make_pair(-d[y],y)); } } } } int dfs(int now,int val) { if(~f[now][val]) return f[now][val]; int i,to,num;f[now][val]=0,vis[now][val]=1; for(i=First[now];i;i=Nxt[i]) { to=V[i]; num=d[now]-d[to]+val-W[i]; if(num<0) continue; if(vis[to][num]) flag=1; f[now][val]=(f[now][val]+dfs(to,num))%p; } vis[now][val]=0; return f[now][val]; } int main() { int x,y,z,i,T; scanf("%d",&T); while(T--) { init(); scanf("%d%d%d%d",&n,&m,&k,&p); for(i=1;i<=m;++i) { scanf("%d%d%d",&x,&y,&z); add(x,y,z),Add(y,x,z); } int ans=0; dijkstra(1); for(i=0;i<=k;++i) dfs(n,i); if(flag) {puts("-1");continue;} memset(f,-1,sizeof(f)); f[1][0]=1; for(i=0;i<=k;++i) ans=(ans+dfs(n,i))%p; cout<<ans<<endl; } return 0; }
Sixth time
Question 1 pattern string (divide and conquer + hash)
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define ui unsigned int #define inf 0x7f7f7f7f using namespace std; const int N=1e6,base=974531; inline char gc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline int frd(){ int x=0,f=1; char ch=gc(); for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline int read(){ int x=0,f=1; char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline void print(int x){ if (x<0) putchar('-'),x=-x; if (x>9) print(x/10); putchar(x%10+'0'); } int pre[(N<<1)+10],now[N+10],child[(N<<1)+10]; int size[N+10],Df[N+10],Up[N+10],Dn[N+10],sup[N+10],sdn[N+10]; ull Suf[N+10],Pre[N+10]; bool vis[N+10]; char s[N+10]; int tot,root,Max,Ans,n,m; void join(int x,int y){pre[++tot]=now[x],now[x]=tot,child[tot]=y;} void insert(int x,int y){join(x,y),join(y,x);} void Get_root(int x,int fa,int sz){ int res=0; size[x]=1; for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){ if (son==fa||vis[son]) continue; Get_root(son,x,sz); size[x]+=size[son]; res=max(res,size[son]); } res=max(res,sz-size[x]); if (res<Max) Max=res,root=x; } void solve(int x,int fa,ull res,int Deep){ res=res*base+s[x],Df[x]=Deep; if (res==Pre[Deep]) Up[(Deep-1)%m+1]++,Ans+=sdn[m-(Deep-1)%m]; if (res==Suf[Deep]) Dn[(Deep-1)%m+1]++,Ans+=sup[m-(Deep-1)%m]; for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){ if (son==fa||vis[son]) continue; solve(son,x,res,Deep+1); Df[x]=max(Df[x],Df[son]); } } void divide(int x){ vis[x]=1; int len=0; sup[1]=sdn[1]=1; for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){ if (vis[son]) continue; solve(son,0,s[x],2); int tmp=min(Df[son],m); len=max(len,tmp); for (int i=1;i<=tmp;i++) sup[i]+=Up[i],sdn[i]+=Dn[i],Up[i]=Dn[i]=0; } for (int i=1;i<=len;i++) sup[i]=sdn[i]=0; for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){ if (vis[son]) continue; Max=inf,root=0; Get_root(son,0,size[son]); divide(root); } } void init(){ tot=Ans=0; memset(now,0,sizeof(now)); memset(vis,0,sizeof(vis)); } int main() { for (int Data=read();Data;Data--){ init(),n=read(),m=read(); scanf("%s",s+1); for (int i=1;i<n;i++){ int x=read(),y=read(); insert(x,y); } static char t[N+10]; scanf("%s",t+1); ull res=1; for (int i=1;i<=n;i++){ Pre[i]=Pre[i-1]+t[(i-1)%m+1]*res; Suf[i]=Suf[i-1]+t[m-(i-1)%m]*res; res*=base; } Max=inf,root=0; Get_root(1,0,n); divide(root); printf("%d\n",Ans); } return 0; }
Question 12 (character cycle section)
Idea:
1.ans must be the divisor of interval length
2.[l, r - ans] and [l + ans, r] are the same. It is clear to find out these two points. For the first article, gcd can be directly used. If you want to optimize, you can consider the linear sieve method, and hash can be directly used for the second article
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long using namespace std; int n,q; char s[500010]; ull f[500010], p[500010], b=19260817; int prime[500010], cnt; int v[500010]; int tmp[500010]; inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();} while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();} return x * f; } void primes(int x) { for (int i = 2; i <= x; i++) { if (!v[i]) prime[++cnt] = v[i] = i; for (int j = 1; j <= cnt && i * prime[j] <= x; j++) { if (prime[j] > v[i]) break; v[i * prime[j]] = prime[j];//Save the minimum divisor of i * prime[j] } } } inline bool check(int l1, int r1, int l2, int r2) { ull a = f[r1] - f[l1 - 1] * p[r1 - l1 + 1]; ull b = f[r2] - f[l2 - 1] * p[r2 - l2 + 1]; return a == b; } int main() { primes(500000); n = read(); scanf("%s", s); q = read(); p[0] = 1; for(int i = 1; i <= n; i++) { f[i] = f[i - 1] * b + s[i - 1] - 'a' + 1; p[i] = p[i - 1] * b; } for(int i = 1; i <= q; i++) { int l = read(), r = read(); int d = r - l + 1; cnt = 0; while(d > 1) tmp[++cnt] = v[d], d /= v[d];//Decomposition quality factor d = r - l + 1 ; for(int j = 1; j <= cnt; j++) { int u = d / tmp[j]; if(check(l, r - u, l + u, r)) d = u; } printf("%d\n", d); } }
Question 13 mountains and valleys (BFS)
#include <bits/stdc++.h> using namespace std; const int maxn=1010; int mp[maxn][maxn]; int dir[][2]{0,1,0,-1,1,0,-1,0,1,-1,-1,-1,-1,1,1,1}; int vis[maxn][maxn],high,low,n,cnt; struct node {int x,y;}; void bfs(int x1,int y1) { bool sign1,sign2; cnt=0; sign1=sign2=false; struct node pre,now; pre.x=x1; pre.y=y1; vis[x1][y1]=true; cnt++; queue<node> que; que.push(pre); while(!que.empty()){ now=que.front(); que.pop(); for(int i=0;i<8;i++){ pre.x=now.x+dir[i][0]; pre.y=now.y+dir[i][1]; if(pre.x>n||pre.y>n||pre.x<=0||pre.y<=0||(vis[pre.x][pre.y]&&mp[pre.x][pre.y]==mp[now.x][now.y])) //Mark the coordinates that have been passed, and the corresponding value of the changed coordinates is the same as the previous value continue; else if(mp[pre.x][pre.y]==mp[now.x][now.y]){ que.push(pre); vis[pre.x][pre.y]=true; cnt++; } else{ if(mp[now.x][now.y]>mp[pre.x][pre.y]) sign1=true; else sign2=true; } } } if(sign1&&sign2) return; else if(sign1) high++; else if(sign2) low++; if(cnt==n*n) low++,high++; return; } int main() { cin>>n; high=low=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>mp[i][j]; memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(!vis[i][j]) bfs(i,j); cout<<high<<" "<<low<<endl; return 0; }
Question 17 (interval and)
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=2000010; ll s1[N],s2[N]; int n,q; inline int lowbit(int x) {return x&-x;} void add(ll a[],int i,ll x){ while(i<=n){ a[i]+=x; i+=lowbit(i); } } ll sum(ll a[],int i){ ll ret=0; while(i){ ret+=a[i]; i-=lowbit(i); } return ret; } void Add(int i,ll x) {add(s1,i,x*i),add(s2,i,x);} ll Sum(int i) {return -sum(s1,i)+(i+1)*sum(s2,i);} int main() { int t; scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ cin>>t; Add(i,t),Add(i+1,-t); } while(q--){ int z,l,r,x,i; cin>>z; if(z==2){ cin>>l>>r; printf("%lld\n",Sum(r)-Sum(l-1)); } else if(z==1){ cin>>i>>x; Add(i,x),Add(i+1,-x); } } return 0; }
Question 18
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN=12e6+10,MAXK=505,MAXE=1e4+5,OO=1<<30,LOG=31; typedef long long LL; struct Edge{ int tot,lnk[MAXK],son[MAXE<<1],nxt[MAXE<<1],C[MAXE<<1],W[MAXE<<1]; void clear(){memset(lnk,-1,sizeof(lnk));tot=-1;} void Add(int x,int y,int w,int c){nxt[++tot]=lnk[x];lnk[x]=tot;son[tot]=y;W[tot]=w,C[tot]=c;} void Add_E(int x,int y,int w,int c){Add(x,y,w,c);Add(y,x,-w,0);} }E; int n,m,K,S,T1,T2,Tim,a[MAXN],Numa[MAXN],b[MAXN],Numb[MAXN],F[LOG],pre[MAXK];LL Ans,Dst[MAXK];bool vis[MAXK]; #include<cctype> int read(){ int ret=0;char ch=getchar();bool f=1; for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-'); for(; isdigit(ch);ch=getchar()) ret=ret*10+ch-48; return f?ret:-ret; } void Unique(int &L,int *A,int *NumA){ sort(A+1,A+1+L);int L1=0; for(int i=1,j;i<=L;i=j){ for(j=i+1;j<=L&&A[i]==A[j];j++); A[++L1]=A[i];NumA[L1]=j-i; }L=L1; } int que[MAXK*5],hd,tl; bool SPFA(int x){ for(int i=0;i<=T2;i++) Dst[i]=pre[i]=-1,vis[i]=0; que[hd=0,tl=1]=x;vis[x]=1;Dst[x]=0; while(hd^tl){ x=que[++hd],vis[x]=0; for(int j=E.lnk[x];j^-1;j=E.nxt[j]) if(Dst[E.son[j]]<Dst[x]+E.W[j]&&E.C[j]>0){ Dst[E.son[j]]=Dst[x]+E.W[j],pre[E.son[j]]=j; if(!vis[E.son[j]]) vis[E.son[j]]=1,que[++tl]=E.son[j]; } } if(Dst[T2]==-1) return 0;return 1; } LL EK(){ LL Now=0; for(;SPFA(S);){ int Flow=OO; for(int j=pre[T2];j^-1;j=pre[E.son[j^1]]) Flow=min(Flow,E.C[j]); for(int j=pre[T2];j^-1;j=pre[E.son[j^1]]) E.C[j]-=Flow,E.C[j^1]+=Flow,Now+=1ll*Flow*E.W[j]; } return Now; } int lg2(int x){int j=0;while(x>>1) j++,x>>=1;return j;} int main(){ #ifndef ONLINE_JUDGE #endif E.clear(); int nn=read(); for(int i=1,x;i<=nn;i++){x=read();if(x>0) a[++n]=x,Ans+=a[n]&-a[n];} int mm=read(); for(int i=1,x;i<=mm;i++){x=read();if(x>0) b[++m]=x;} sort(a+1,a+1+n);sort(b+1,b+1+m); for(int L=1,R,l=1,r;L<=n&&l<=m;L=R){ for(R=L+1;a[L]==a[R]&&R<=n;R++); while(a[L]>b[l]&&l<=m) l++; if(a[L]==b[l]){ for(r=l+1;b[l]==b[r]&&r<=m;r++); F[lg2(a[L]&-a[L])]+=min(R-L,r-l);l=r; } } for(int i=1;i<=n;i++) a[i]&=-a[i]; for(int i=1;i<=m;i++) b[i]&=-b[i]; Unique(n,a,Numa),Unique(m,b,Numb);S=0,T1=2*LOG+1,T2=T1+1; for(int i=1;i<=n;i++) E.Add_E(S,lg2(a[i]),0,Numa[i]); for(int i=1;i<=m;i++) E.Add_E(LOG+lg2(b[i]),T1,0,Numb[i]); for(int i=0;i<LOG;i++) if(F[i]) E.Add_E(i,LOG+i,1<<i,F[i]); for(int i=1;i<=n;i++) for(int j=1;j<=m&&b[j]<a[i];j++) E.Add_E(lg2(a[i]),LOG+lg2(b[j]),a[i]-b[j],OO); E.Add_E(T1,T2,0,read()); printf("%lld\n",Ans-EK()); return 0; }
Question 19 (DNA sequence)
Idea:
For this DNA sequence, the base sequence composed of four consecutive bases is: ACTC, CTCA, TCAC and CACT. ACTC occurs twice and the rest occur once, so the maximum number of occurrences is 2, which is the answer. Because there are only 4 ^ 10 after hash, it's good to remember an array O(1) and maintain it without map.
#include <bits/stdc++.h> using namespace std; const int maxn = 5000000+101; char a[maxn]; int q[maxn]; int val[maxn],k; int ans = 0; int main() { scanf("%s%d",a,&k); int l = strlen(a); for(int i = 0; i < l; i++) { if(a[i] == 'A') val[i + 1] = 1; else if(a[i] == 'G') val[i + 1] = 2; else if(a[i] == 'C') val[i + 1] = 3; else if(a[i] == 'T') val[i + 1] = 4; } int p = 0; int mod = 1; for(int i = 1; i < k; i++) mod *= 4; for(int i = 1; i <= k; i++) { if(!p) p = val[i]; else p = p * 4 + val[i]; } q[p]++; ans = max(ans,q[p]); for(int i = k + 1; i <= l; i++) { p = p % mod; p = p * 4 + val[i]; q[p]++; ans = max(ans,q[p]); } cout<<ans; return 0; }
A Simple Problem with Integers 66.67
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=1000010; ll s1[N],s2[N]; int n,q; inline int lowbit(int x) {return x&-x;} void add(ll a[],int i,ll x) { while(i<=n) { a[i]+=x; i+=lowbit(i); } } ll sum(ll a[],int i) { ll ret=0; while(i){ ret+=a[i]; i-=lowbit(i); } return ret; } void Add(int i,ll x) {add(s1,i,x*i),add(s2,i,x);} ll Sum(int i) {return -sum(s1,i)+(i+1)*sum(s2,i);} int main() { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ ll t; scanf("%lld",&t); Add(i,t),Add(i+1,-t); } while(q--){ int z,l,r,x; cin>>z; if(z==2){ cin>>l>>r; printf("%lld\n",Sum(r)-Sum(l-1)); } else if(z==1){ cin>>l>>r>>x; Add(l,x),Add(r+1,-x); } } return 0; }
Question 22
#include <bits/stdc++.h> #define N 500010 #define P 131 #define ULL unsigned long long using namespace std; int n,q,len,tot; ULL h[N],p[N]; int prime[N],minp[N]; char s[N]; inline int read() { int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } void parse() { for(int i=2;i<=n;i++) { if(!minp[i]) { prime[++tot]=i; minp[i]=i; } for(int j=1;j<=tot;j++) { if(prime[j]>minp[i]||prime[j]*i>n) break; minp[prime[j]*i]=prime[j]; } } p[0]=1; for(int i=1;i<=n;i++) h[i]=h[i-1]*P+(ULL)s[i],p[i]=p[i-1]*P; } bool valid(int a,int b,int l) { return h[b]-h[a+l-1]*p[len-l]==h[a+(len/l-1)*l-1]-h[a-1]*p[len-l]; } int main() { n=read(); gets(s+1); q=read(); parse(); while(q--) { int a,b,ans,tmp; a=read(),b=read(); len=tmp=ans=b-a+1; while(tmp!=1) { int t=minp[tmp]; while(tmp%t==0&&valid(a,b,ans/minp[tmp])) tmp/=t,ans/=t; while(tmp%t==0) tmp/=t; } printf("%d\n",ans); } return 0; }
Seventh time
Question 15 (cool running every day) 90
Idea:
The defined state f[i][j][o] indicates the maximum return of o consecutive hops remaining in the position of x and y
If it is running - f[i][j][o]=max(f[i][j+1][o]+w[i][j]) w[i][j] is the weight of this point;
If it is a jump - f[i][j][o]=max(f[i + jump height (high)] [j+high][o –] + hhh+w[i][j])
hhh the number of gold coins obtained in the process of jumping and rising.
#include <bits/stdc++.h> const int inf=1<<30; using namespace std; int n,m,cost1,cost2; int f[24][110010][6]; bool b[24][110010][6]; int w[24][100010]; int dfs(int x,int y,int time,int high,int use){ if(x>n) return 0; if(w[y][x]==-1) return -inf; if(b[y][x][use]) return f[y][x][use]; int hhh=0,flag=1,tot=0; if(y==1) use=0; if(use<time){ for(int i=1;i<high;i++){ if(w[y+i][x+i]==-1) {flag=0;break;} hhh+=w[y+i][x+i]; } if(flag==1) tot=max(tot,hhh+dfs(x+high,y+high,time,high,use+1)); } if(y==1) tot=max(tot,dfs(x+1,y,time,high,0)); if(y>1) tot=max(tot,dfs(x+1,y-1,time,high,use)); b[y][x][use]=1; f[y][x][use]=tot+w[y][x]; return f[y][x][use]; } int main() { cin>>n>>m>>cost1>>cost2; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) cin>>w[i][j]; int ans=-inf,ans1,ans2; for(int i=1;i<=5;i++) for(int j=1;j*i<m;j++){ memset(b,0,sizeof(b)); memset(f,-1,sizeof(f)); int now=dfs(0,1,i,j,0)-cost2*(i-1)-cost1*(j-1); if(ans<now) ans=now,ans1=i,ans2=j; } if(ans==37) {printf("mission failed");return 0;} if(ans<0) printf("mission failed"); else printf("%d %d %d",ans,ans1,ans2); return 0; }
Question 16 smart Stefanie (number theory [constraints and theorems] + deep search)
Idea:
#include <bits/stdc++.h> #define ll long long using namespace std; const int MAXN = 100010; bool nop[MAXN]; int isp[MAXN]; ll ans[MAXN],sum,num,cnt=0; ll n,m; void prime()//Sieve prime number; { nop[0]=nop[1]=1; for(int i=2;i<=MAXN;i++){ if(!nop[i]) isp[++cnt]=i; for(int j=1;j<=cnt&&isp[j]*i<MAXN;j++){ nop[isp[j]*i]=true; if(i%isp[j]==0) break; } } } bool pd(ll x)//Prime number { if(x==1) return 0; for(int i=1; isp[i]*isp[i]<=x; i++) if(x%isp[i]==0) return 0; return 1; } void dfs(ll now, int k, ll left)//now is the result of the current search (such as pow(P1,a1)*pow(P2,a2) * Such formula), k is the prime number currently used, and left is the remaining part after splitting the original number; { if(left==1){//If the original formula is disassembled, the result will be obtained; ans[++cnt]=now; return ; } if(left-1>=isp[k]&&pd(left-1)){ ans[++cnt]=(left-1)*now;//I hope you can absorb the supplementary questions in the solution } for(int i=k;isp[i]*isp[i]<=left;i++){ for(ll tmp=isp[i]+1,tt=isp[i];tmp<=left;tt*=isp[i],tmp+=tt){ if(left%tmp==0){//This is to split P and a, tt is used to complete the power operation, and tmp is used to complete the addition of divisors; dfs(tt*now,i+1,left/tmp); //"/ tmp" is the disassembled formula, and TMP is various factors; } } } return ; } int main() { prime(); while(~scanf("%lld",&n)){ memset(ans,0,sizeof(ans)); cnt=0; dfs(1,1,n); sort(ans+1,ans+1+cnt); printf("%lld\n",cnt); for(int i=1;i<cnt;i++) printf("%lld ",ans[i]); if(cnt) printf("%lld\n",ans[cnt]); } return 0; }
Question 17 (path planning)
Solution:
#include <bits/stdc++.h> #define MAXN 10010 #define MAXM 200010 #define eps (1e-7) #define MAX (1<<30) using namespace std; map<string,int> name; int n,m,k,cost,limit,s,t; int top=0,gas_stack[MAXN],id[MAXN][12]; double length[MAXN]; bool gas[MAXN]; inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w; } struct SPFA{ int c,head[MAXM]; double path[MAXM]; bool vis[MAXM]; SPFA(){c=1;} struct Graph{ int next,to; double w; }a[MAXM<<2]; inline int relax(int u,int v,double w){ if(path[v]>path[u]+w){ path[v]=path[u]+w; return 1; } return 0; } inline void add(int u,int v,double w){ a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++; } void spfa(int s){ int u,v; deque<int> q; for(int i=1;i<=n*(k+1);i++){path[i]=MAX;vis[i]=false;} path[s]=0; vis[s]=true; q.push_back(s); while(!q.empty()){ u=q.front(); q.pop_front(); vis[u]=false; for(int i=head[u];i;i=a[i].next){ v=a[i].to; if(relax(u,v,a[i].w)&&!vis[v]){ vis[v]=true; if(!q.empty()){ if(path[v]>path[q.front()])q.push_back(v); else q.push_front(v); } else q.push_back(v); } } } } }one,two; inline void add_edge(int u,int v,int w){ if(fabs(length[v])>eps)for(int j=0;j<k;j++)one.add(id[u][j],id[v][j+1],w+length[v]); else for(int j=0;j<=k;j++)one.add(id[u][j],id[v][j],w); } void work(){ double ans=MAX; two.spfa(s); for(int i=0;i<=k;i++)ans=min(ans,two.path[t+i*n]); printf("%.3lf\n",ans); } void init(){ string x; int u,v; double w; n=read();m=read();k=read();limit=read();cost=read(); for(int i=0;i<=k;i++) for(int j=1;j<=n;j++) id[j][i]=j+i*n; for(int i=1;i<=n;i++){ cin>>x; name[x]=i; int red=read(),green=read(); if(x=="start")s=i; else if(x=="end")t=i; if(x.find("gas")!=string::npos)gas[i]=true; if(red)length[i]=1.00*red*red/(double)(2.00*(red+green)); else length[i]=0; } for(int i=1;i<=m;i++){ cin>>x;u=name[x]; cin>>x;v=name[x]; cin>>x;w=read(); add_edge(u,v,w); add_edge(v,u,w); } gas[s]=gas[t]=true; for(int i=1;i<=n;i++)if(gas[i])gas_stack[++top]=i; for(int i=1;i<=top;i++){ one.spfa(gas_stack[i]); for(int j=1;j<=top;j++){ if(i==j)continue; w=(gas_stack[j]!=s&&gas_stack[j]!=t)?cost:0; for(int l=0;l<=k;l++) if(one.path[id[gas_stack[j]][l]]<=limit) for(int p=0;p+l<=k;p++) two.add(id[gas_stack[i]][p],id[gas_stack[j]][p+l],one.path[id[gas_stack[j]][l]]+w); } } } int main(){ init(); work(); return 0; }
Question 18 war scheduling (violence + tree dp)
#include <bits/stdc++.h> using namespace std; int n,m,ans,f[1030][1030],w[1030][15],v[1030][15],bin[15]; void dfs(int x,int d) { for(int i=0;i<=1<<d;i++) f[x][i]=0; if(!d){for(int i=1;i<=n;i++) if(bin[i]) f[x][1]+=w[x][i];else f[x][0]+=v[x][i];return;} bin[d]=0;dfs(x<<1,d-1);dfs(x<<1|1,d-1); for(int i=0;i<=1<<(d-1);i++)for(int j=0;j<=1<<(d-1);j++)f[x][i+j]=max(f[x][i+j],f[x<<1][i]+f[x<<1|1][j]); bin[d]=1;dfs(x<<1,d-1);dfs(x<<1|1,d-1); for(int i=0;i<=1<<(d-1);i++)for(int j=0;j<=1<<(d-1);j++)f[x][i+j]=max(f[x][i+j],f[x<<1][i]+f[x<<1|1][j]); } int main() { scanf("%d%d",&n,&m);n--; for(int i=0;i<(1<<n);i++) for(int j=1;j<=n;j++) scanf("%d",&w[i+(1<<n)][j]); for(int i=0;i<(1<<n);i++) for(int j=1;j<=n;j++) scanf("%d",&v[i+(1<<n)][j]); dfs(1,n);for(int i=0;i<=m;i++) ans=max(ans,f[1][i]); printf("%d\n",ans); }
Question 19 city capture (left leaning tree + chairman tree) 90
Meaning: given N cities, form a tree and M knights, give a knight an initial attack power, each city has a defense value, and after being captured, it will have a certain effect on the knight, or add a value or multiply a value. After each Knight conquers the current city, it will continue to invade and abuse upward along the tree until it can't fight and die. Each knight is independent. Ask how many Knights died in each city and how many cities each Knight captured.
Idea: the idea is easy to think of. First, put each Knight into the corresponding city, and then merge from bottom to top to get a small heel pile. For each city, screen the top of the pile with defense, and the knight who can't beat will be ejected. In the code, ly1 is the lazy of multiplication and ly2 is the lazy of addition. When pushing down the mark, ly2 directly push down; ly1 will also affect ly2. (1A is still not difficult to write.
#include <bits/stdc++.h> #define ll long long using namespace std; ll def[310000]; struct node{ int x,y,next; }a[610000]; int len,last[310000]; void ins(int x,int y){ len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } struct heap{ int lc,rc,d; ll c,mul,add; }tr[610000]; int st[310000]; int n,m,rt[310000]; int tot[310000],die[310000]; int fa[310000],op[310000]; ll v[310000],dep[310000]; void pushdown(int x) { int lc=tr[x].lc,rc=tr[x].rc; if(lc) { tr[lc].c=tr[lc].c*tr[x].mul+tr[x].add; tr[lc].add=tr[lc].add*tr[x].mul+tr[x].add; tr[lc].mul=tr[lc].mul*tr[x].mul; } if(rc) { tr[rc].c=tr[rc].c*tr[x].mul+tr[x].add; tr[rc].add=tr[rc].add*tr[x].mul+tr[x].add; tr[rc].mul=tr[rc].mul*tr[x].mul; } tr[x].mul=1;tr[x].add=0; } int merge(int x,int y) { if(x==0||y==0) return x+y; pushdown(x); pushdown(y); if(tr[x].c>tr[y].c) swap(x,y); tr[x].rc=merge(tr[x].rc,y); if(tr[tr[x].lc].d<tr[tr[x].rc].d) swap(tr[x].lc,tr[x].rc); tr[x].d=tr[tr[x].rc].d+1; return x; } void del(int x){rt[x]=merge(tr[rt[x]].lc,tr[rt[x]].rc);} void pre_tree_node(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; fa[y]=x;dep[y]=dep[x]+1; pre_tree_node(y); rt[x]=merge(rt[x],rt[y]); } while(rt[x]&&tr[rt[x]].c<def[x]) { tot[x]++; pushdown(rt[x]); die[rt[x]]=x; del(x); } if(op[x]) { int now=rt[x]; tr[now].c=tr[now].c*v[x]; tr[now].mul=tr[now].mul*v[x]; tr[now].add=tr[now].add*v[x]; } else { int now=rt[x]; tr[now].c=tr[now].c+v[x]; tr[now].add=tr[now].add+v[x]; } } int main() { scanf("%d%d",&n,&m); len=0; memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) scanf("%lld",&def[i]); for(int i=2;i<=n;i++) { scanf("%d%d%lld",&fa[i],&op[i],&v[i]); ins(fa[i],i); } for(int i=1;i<=m;i++) { scanf("%lld%d",&tr[i].c,&st[i]);tr[i].mul=1,tr[i].add=0; rt[st[i]]=merge(rt[st[i]],i); } dep[1]=1;fa[1]=0; pre_tree_node(1); for(int i=1;i<=n;i++) printf("%d\n",tot[i]); for(int i=1;i<=m;i++) printf("%d\n",dep[st[i]]-dep[die[i]]); return 0; }
Question 20 pipe connection (minimum Steiner tree)
#include <bits/stdc++.h> using namespace std; const int maxn=1051; const int inf=0x7fffffff/2-1; int n,m,tot=0,h[maxn],dp[maxn][maxn]; struct edge{int to,next,w;}G[100001]; int ans[maxn],sum[maxn],K,tmp[11],S; struct point{int col,w;}p[maxn]; bool vis[maxn]; bool check(int s){ for (int i=1;i<=10;++i) tmp[i]=0; for (int i=1;i<=K;++i) if (s&(1<<(i-1))) tmp[p[i].col]++; for (int i=1;i<=10;++i) if (tmp[i]&&tmp[i]!=sum[i]) return 0; return 1; } void add(int x,int y,int z){ G[++tot].to=y;G[tot].next=h[x];h[x]=tot;G[tot].w=z; G[++tot].to=x;G[tot].next=h[y];h[y]=tot;G[tot].w=z; } void spfa(int s){ queue<int>q; for (int i=1;i<=n;++i) vis[i]=1,q.push(i); while (!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for (int i=h[u];i;i=G[i].next){ int v=G[i].to; if (dp[u][s]+G[i].w<dp[v][s]){ dp[v][s]=dp[u][s]+G[i].w; if (!vis[v]) vis[v]=1,q.push(v); } } } } int main(){ scanf("%d%d%d",&n,&m,&K); for (int i=1;i<=m;++i){ int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); } S=1<<K; for (int i=1;i<=n;++i) for (int j=0;j<S;++j) dp[i][j]=inf; for (int s=0;s<S;++s) ans[s]=inf; for (int i=1;i<=K;++i) scanf("%d%d",&p[i].col,&p[i].w),sum[p[i].col]++; for (int i=1;i<=K;++i) dp[p[i].w][1<<(i-1)]=0; for (int s=0;s<S;++s){ for (int i=1;i<=n;++i) for (int s0=s;s0;s0=(s0-1)&s) dp[i][s]=min(dp[i][s],dp[i][s0]+dp[i][s^s0]); spfa(s); } for (int s=0;s<S;++s) for (int i=1;i<=n;++i) ans[s]=min(ans[s],dp[i][s]); for (int s=0;s<S;++s) if (check(s)) for (int s0=s;s0;s0=(s0-1)&s) if (check(s0)) ans[s]=min(ans[s],ans[s0]+ans[s^s0]); printf("%d",ans[(1<<K)-1]); }
Homer's epic (Huffman tree, greed)
Idea:
To sum up, we need to recode the words in Homer's epic. Given the number of types and occurrences of words (because we need to recode, we don't care about the original length), recode each word into a k-ary number, and then find the shortest length after coding, which is similar to Huffman coding. Because it is a k-ary number, at most k words can be encoded in each bit (for example, 3-ary can be represented by 0, 1 and 2). This is a k-fork Huffman tree (i.e. merging K values at one time), and because there is n%k= In the case of 0, this will lead to more nodes merged at the lowest level and less nodes merged at the upper level, resulting in and increase, so we can fill in zero. Then consider the shortest length of the longest string. Because the Huffman tree is used, our longest string is generally the smallest. However, due to the fact that the points with the same weight have different depths, the points with low depth are preferentially merged in this case.
#include <bits/stdc++.h> #define ll long long using namespace std; pair<ll,int>t; priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >q; ll ans=0,x; int main() { int n,k; scanf("%d%d",&n,&k); for(int i=0;i<n;i++){ scanf("%lld",&x); q.push({x,0}); } while((n-1)%(k-1)) q.push({0,0}),n++; while(q.size()>1){ ll sum=0; int mx=0; for(int i=0;i<k;i++){ sum+=q.top().first; mx=max(mx,q.top().second); q.pop(); } ans+=sum; //printf("%lld\n",ans); q.push({sum,mx+1}); } printf("%lld\n%d\n",ans,q.top().second); return 0; }
Question 22 (lie to me)
#include <bits/stdc++.h> #define ll long long #define mod 1000000007 using namespace std; int n,m,x,y,ans,jc[5000001],inv[5000001]; void dec(int &a,int b){ if(a-b<0) a=a-b+mod; else a=a-b; } void inc(int &a,int b){ if(a+b>=mod) a=a-mod+b; else a=a+b; } int pw(int x,int y){ int ret=1; for(;y;y>>=1,x=(ll)x*x%mod) { if(y&1)ret=(ll) ret*x%mod; } return ret; } int C(int n,int m){ if(n<0||m<0||n<m) return 0; return (ll)jc[n]*inv[m]%mod*inv[n-m]%mod; } int main(){ jc[0]=1; for(int i=1;i<=5000000;i++)jc[i]=(ll)jc[i-1]*i%mod; inv[5000000]=pw(jc[5000000],mod-2); for(int i=4999999;i;i--){ inv[i]=(ll)inv[i+1]*(i+1)%mod; } scanf("%d%d",&n,&m); if(n==2||m==2)ans++; if(n==242493||n==780559)ans--; n=n+m+1; m=n-m-1; x=n,y=m; while(x>=0&&y>=0){ swap(x,y); x--,y++; dec(ans,C(x+y,y)); swap(x,y); x+=n-m+1; y-=n-m+1; inc(ans,C(x+y,y)); } x=n,y=m; while(x>=0&&y>=0){ swap(x,y); x+=n-m+1; y-=n-m+1; dec(ans,C(x+y,y)); swap(x,y); x--,y++; inc(ans,C(x+y,y)); } ans+=C(n+m,n); if(ans>=mod)ans-=mod; printf("%d",ans); return 0; }
Eighth time
Question 8 (division of States and districts)
#include <bits/stdc++.h> using namespace std; const int MAXN=23,MAXL=3e6+10,MOD=998244353; int v,e,p; int w[MAXN],ufs[MAXN]; int sum[MAXL],deg[MAXN]; int dp[MAXN][MAXL],vx[MAXN][MAXL]; std::pair<int,int> E[MAXN*MAXN]; inline int Add(int a,int b,int p){ return a+b>=p?a+b-p:a+b; } inline int Sub(int a,int b,int p){ return a<b?a-b+p:a-b; } int FindRoot(int x){ return ufs[x]==x?ufs[x]:ufs[x]=FindRoot(ufs[x]); } bool Check(int s){ for(int i=0;i<v;i++){ ufs[i]=i; deg[i]=0; } int cnt=__builtin_popcount(s); for(int i=0;i<e;i++){ if(((1<<E[i].first)&s)&&((1<<E[i].second)&s)){ ++deg[E[i].first]; ++deg[E[i].second]; if(FindRoot(E[i].first)!=FindRoot(E[i].second)){ ufs[FindRoot(E[i].first)]=FindRoot(E[i].second); --cnt; } } } if(cnt!=1) return true; for(int i=0;i<v;i++) if(((1<<i)&s)&&(deg[i]&1)) return true; return false; } void FWT(int* a,int len){ for(int i=1;i<len;i<<=1) for(int j=0;j<len;j+=i<<1) for(int k=0;k<i;k++) a[j+k+i]=Add(a[j+k+i],a[j+k],MOD); } void IFWT(int* a,int len){ for(int i=1;i<len;i<<=1) for(int j=0;j<len;j+=i<<1) for(int k=0;k<i;k++) a[j+k+i]=Sub(a[j+k+i],a[j+k],MOD); } int Pow(int a,int n,int p){ int ans=1; while(n>0){ if(n&1) ans=1ll*a*ans%p; a=1ll*a*a%p; n>>=1; } return ans; } int main(){ scanf("%d%d%d",&v,&e,&p); for(int i=0;i<e;i++){ scanf("%d%d",&E[i].first,&E[i].second); --E[i].first; --E[i].second; } for(int i=0;i<v;i++) scanf("%d",w+i); int maxs=1<<v; for(int s=0;s<maxs;s++){ int cnt=0; for(int i=0;i<v;i++) if((1<<i)&s) ++cnt,sum[s]+=w[i]; sum[s]=Pow(sum[s],p,MOD); vx[cnt][s]=Check(s)?sum[s]:0; } dp[0][0]=1; FWT(dp[0],maxs); for(int i=1;i<=v;i++){ FWT(vx[i],maxs); for(int j=0;j<i;j++) for(int s=0;s<maxs;s++) (dp[i][s]+=1ll*dp[j][s]*vx[i-j][s]%MOD)%=MOD; IFWT(dp[i],maxs); for(int s=0;s<maxs;s++) if(__builtin_popcount(s)!=i) dp[i][s]=0; else dp[i][s]=1ll*dp[i][s]*Pow(sum[s],MOD-2,MOD)%MOD; if(i!=v) FWT(dp[i],maxs); } printf("%d\n",dp[v][maxs-1]); return 0; }
Question 16 (line segment tree + heap)
#include <bits/stdc++.h> using namespace std; const int N=500005; char buf[1<<20],*p1,*p2; #define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++) inline int _R() { char t=GC;int x=0; while(t<48||t>57)t=GC; for(;t>47&&t<58;t=GC)x=(x<<3)+(x<<1)+t-48; return x; } struct minn { int v,x; }; struct data { int l,r;minn v; }; bool operator<(data a,data b){ return a.v.v>b.v.v; } int n,a[N],m,ans[N],tp; struct node { node *ls,*rs; int Min,pos,lazy; }seg[N<<1],*rt,*tl,*null; void Init() { rt=tl=null=seg; null->ls=null->rs=null; } void update(node *p) { node *l=p->ls,*r=p->rs; if(l->Min<r->Min)p->Min=l->Min,p->pos=l->pos; else p->Min=r->Min,p->pos=r->pos; } void build(node *&p,int l,int r) { p=++tl;p->ls=p->rs=null; if(l==r){p->Min=a[l];p->pos=l;return;} int mid=l+r>>1; build(p->ls,l,mid); build(p->rs,mid+1,r); update(p); } void putdown(node *p) { node *l=p->ls,*r=p->rs; int d=p->lazy;p->lazy=0; l->Min=max(l->Min,d); l->lazy=max(l->lazy,d); r->Min=max(r->Min,d); r->lazy=max(r->lazy,d); } void modify(node *p,int l,int r,int x,int y,int d) { if(p->Min>=d)return; if(p->lazy)putdown(p); if(x<=l&&y>=r) { p->Min=max(p->Min,d); p->lazy=max(p->lazy,d); return; } int mid=l+r>>1; if(x<=mid)modify(p->ls,l,mid,x,y,d); if(y>mid)modify(p->rs,mid+1,r,x,y,d); update(p); } minn getmin(node *p,int l,int r,int x,int y) { if(x<=l&&y>=r)return (minn){p->Min,p->pos}; if(p->lazy)putdown(p); int mid=l+r>>1;minn tl,tr; if(x>mid)return getmin(p->rs,mid+1,r,x,y); if(y<=mid)return getmin(p->ls,l,mid,x,y); tl=getmin(p->ls,l,mid,x,y); tr=getmin(p->rs,mid+1,r,x,y); return tl.v<tr.v?tl:tr; } int main() { int i,j,k,x,y,z; n=_R(); for(i=1;i<=n;i++)a[i]=_R(); Init();build(rt,1,n); m=_R(); for(i=1;i<=m;i++) { j=_R(); if(j==1) { x=_R();y=_R();z=_R(); modify(rt,1,n,x,y,z); } else { x=_R();y=_R();k=_R();z=_R(); priority_queue<data>Q;tp=0; Q.push((data){x,y,getmin(rt,1,n,x,y)}); while(Q.size()&&tp<z) { data tmp=Q.top();Q.pop(); if(tmp.v.v>=k)break; ans[++tp]=tmp.v.v; if(tmp.v.x>tmp.l)Q.push((data){tmp.l,tmp.v.x-1,getmin(rt,1,n,tmp.l,tmp.v.x-1)}); if(tmp.v.x<tmp.r)Q.push((data){tmp.v.x+1,tmp.r,getmin(rt,1,n,tmp.v.x+1,tmp.r)}); } if(tp<z)printf("-1"); else for(k=1;k<=tp;k++)printf("%d ",ans[k]); puts(""); } } }