ABC267 - C,D,E,F Solutions
C - Index × A(Continuous ver.)
Problem Statement
You are given an integer sequence of length .
Find the maximum value of for a contiguous subarray of of length .
Constraints
Solution
不妨令 ,其中 。直接计算是 的,需要进行优化。
首先可以考虑 与 的关系,会发现 ,于是简单前缀和就解决了。
另外也可以直接求,对 与 都求前缀和, 即为两者做差的形式,此处不再赘述。
Implementation
signed main(){ n=rd();m=rd();jk(i,1,n)a[i]=rd(); jk(i,1,n)s[i]=s[i-1]+a[i]; jk(i,1,m)R+=a[i]*i;r=R; jk(i,m+1,n)r=std::max(r,R=R-(s[i-1]-s[i-m-1])+m*a[i]); P(r); }
D - Index × A(Not Continuous ver.)
Problem Statement
You are given an integer sequence of length .
Find the maximum value of for a (not necessarily contiguous) subsequence of length of .
Constraints
Solution
和上题不一样的地方在于 的选择可以不连续,不难想到可以通过 dp 进行求解,于是令 表示 中,选择了 个数时 最大的值。故转移方程为 。
Implementation
可能为负数,需要注意边界条件。
#define IN -1000000000000000000ll signed main(){ n=rd();m=rd();jk(i,1,n)a[i]=rd(); jk(i,1,n)jk(j,1,n)f[i][j]=IN; f[0][1]=IN; //Important! jk(i,1,n)jk(j,1,i)f[i][j]=std::max(f[i-1][j],f[i-1][j-1]+j*a[i]); P(f[n][m]); }
E - Erasing Vertices 2
Problem Statement
You are given a simple undirected graph with vertices and edges. The -th edge connects Vertices and . Vertex has a positive integer written on it.
You will repeat the following operation times.
- Choose a Vertex that is not removed yet, and remove Vertex and all edges incident to Vertex . The cost of this operation is the sum of the integers written on the vertices directly connected by an edge with Vertex that are not removed yet.
We define the cost of the entire operations as the maximum of the costs of the individual operations. Find the minimum possible cost of the entire operations.
Constraints
- The given graph is simple.
Solution
Minimize the maximum. 经典二分答案,需要注意删掉一个点时会导致相邻点的代价变小,所以开一个队列,在删掉后将相邻满足条件的点加到队列里。
Implementation
bool ck(int x){ memcpy(s,S,(n+1)*sizeof(int));memset(de,0,sizeof de); std::queue<int>q; jk(i,1,n)if(s[i]<=x)q.push(i); while(!q.empty()){ int u=q.front();q.pop();if(de[u])continue;de[u]=1; for(int i=h[u];i;i=e[i].n){ int v=e[i].v;if(de[v])continue; if((s[v]-=V[u])<=x)q.push(v); } } jk(i,1,n)if(!de[i])return 0; return 1; } signed main(){ n=rd();m=rd();jk(i,1,n)V[i]=rd(); int u,v;jk(i,1,m){u=rd();v=rd();ad(u,v);ad(v,u);} jk(u,1,n)for(int i=h[u];i;i=e[i].n)S[u]+=V[e[i].v]; int l=0,r=MX*2,mi;while(l<r){mi=(l+r)>>1;if(ck(mi))r=mi;else l=mi+1;} P(l); }
F - Exactly K Steps
Problem Statement
You are given a tree with vertices. The vertices are numbered , and the -th () edge connects Vertices and .
We define the distance between Vertices and on this tree by the number of edges in the shortest path from Vertex to Vertex .
You are given queries. In the -th () query, given integers and , print the index of any vertex whose distance from Vertex is exactly . If there is no such vertex, print -1
.
Constraints
- The given graph is a tree.
Solution
需要知道一个性质:令直径两端点为 与 ,则对于树中的任意节点 , 到 的路径与 到 的路径中必有一条为 点出发可达的最长路径,此处性质在两边dfs求直径的方法中被证明过。
于是先求出直径,然后分别以 与 为根建两棵树,使用树上倍增找点。
另:官方题解中把询问离线下来, 地解决了,回来补下这个做法。
Implementation
void df(int u,int f,int o){ D[u][o]=D[f][o]+1;F[u][0][o]=f; if(o)jk(i,1,L)F[u][i][o]=F[F[u][i-1][o]][i-1][o]; for(int i=h[u];i;i=e[i].n)if(e[i].v!=f)df(e[i].v,u,o); } void pr(){ int mx,mi;df(1,0,0); mx=D[1][0],mi=1;jk(i,2,n)if(D[i][0]>mx)mx=D[i][0],mi=i; memset(D,0,sizeof D);X=mi;df(mi,0,0); mx=D[1][0],mi=1;jk(i,2,n)if(D[i][0]>mx)mx=D[i][0],mi=i; Y=mi;df(X,0,1);df(Y,0,2); } int fi(int x,int d,int o){jk(i,0,L)if((d>>i)&1)x=F[x][i][o];return x;} int wk(int x,int d){jk(o,1,2)if(D[x][o]>d)return fi(x,d,o);return -1;}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】