You are given an integer sequence of length .
Find the maximum value of for a contiguous subarray of of length .
Constraints
不妨令 ,其中 。直接计算是 的,需要进行优化。
首先可以考虑 与 的关系,会发现 ,于是简单前缀和就解决了。
另外也可以直接求,对 与 都求前缀和, 即为两者做差的形式,此处不再赘述。
1signed main(){
2 n=rd();m=rd();jk(i,1,n)a[i]=rd();
3 jk(i,1,n)s[i]=s[i-1]+a[i];
4 jk(i,1,m)R+=a[i]*i;r=R;
5 jk(i,m+1,n)r=std::max(r,R=R-(s[i-1]-s[i-m-1])+m*a[i]);
6 P(r);
7}
You are given an integer sequence of length .
Find the maximum value of for a (not necessarily contiguous) subsequence of length of .
Constraints
和上题不一样的地方在于 的选择可以不连续,不难想到可以通过 dp 进行求解,于是令 表示 中,选择了 个数时 最大的值。故转移方程为 。
可能为负数,需要注意边界条件。
xxxxxxxxxx
81
2signed main(){
3 n=rd();m=rd();jk(i,1,n)a[i]=rd();
4 jk(i,1,n)jk(j,1,n)f[i][j]=IN;
5 f[0][1]=IN; //Important!
6 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]);
7 P(f[n][m]);
8}
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.
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
Minimize the maximum. 经典二分答案,需要注意删掉一个点时会导致相邻点的代价变小,所以开一个队列,在删掉后将相邻满足条件的点加到队列里。
x1bool ck(int x){
2 memcpy(s,S,(n+1)*sizeof(int));memset(de,0,sizeof de);
3 std::queue<int>q;
4 jk(i,1,n)if(s[i]<=x)q.push(i);
5 while(!q.empty()){
6 int u=q.front();q.pop();if(de[u])continue;de[u]=1;
7 for(int i=h[u];i;i=e[i].n){
8 int v=e[i].v;if(de[v])continue;
9 if((s[v]-=V[u])<=x)q.push(v);
10 }
11 }
12 jk(i,1,n)if(!de[i])return 0;
13 return 1;
14}
15
16signed main(){
17 n=rd();m=rd();jk(i,1,n)V[i]=rd();
18 int u,v;jk(i,1,m){u=rd();v=rd();ad(u,v);ad(v,u);}
19 jk(u,1,n)for(int i=h[u];i;i=e[i].n)S[u]+=V[e[i].v];
20 int l=0,r=MX*2,mi;while(l<r){mi=(l+r)>>1;if(ck(mi))r=mi;else l=mi+1;}
21 P(l);
22}
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
需要知道一个性质:令直径两端点为 与 ,则对于树中的任意节点 , 到 的路径与 到 的路径中必有一条为 点出发可达的最长路径,此处性质在两边dfs求直径的方法中被证明过。
于是先求出直径,然后分别以 与 为根建两棵树,使用树上倍增找点。
另:官方题解中把询问离线下来, 地解决了,回来补下这个做法。
xxxxxxxxxx
171void df(int u,int f,int o){
2 D[u][o]=D[f][o]+1;F[u][0][o]=f;
3 if(o)jk(i,1,L)F[u][i][o]=F[F[u][i-1][o]][i-1][o];
4 for(int i=h[u];i;i=e[i].n)if(e[i].v!=f)df(e[i].v,u,o);
5}
6
7void pr(){
8 int mx,mi;df(1,0,0);
9 mx=D[1][0],mi=1;jk(i,2,n)if(D[i][0]>mx)mx=D[i][0],mi=i;
10 memset(D,0,sizeof D);X=mi;df(mi,0,0);
11 mx=D[1][0],mi=1;jk(i,2,n)if(D[i][0]>mx)mx=D[i][0],mi=i;
12 Y=mi;df(X,0,1);df(Y,0,2);
13}
14
15int fi(int x,int d,int o){jk(i,0,L)if((d>>i)&1)x=F[x][i][o];return x;}
16int wk(int x,int d){jk(o,1,2)if(D[x][o]>d)return fi(x,d,o);return -1;}
17