D
题意
一棵树。
求最长两点路径,并且路径上所有的
题解
可以考虑,因为
所有每个点的值最大质因数不超过个。算个。
表示从开始到子树内的最大长度。
,是子结点值的因数中的位置,是的第个质因数。
但显然这样是不行的,会因为存在两个不在一条链上(我们在过程人为规定了直链),所以对,要处理出子结点值最大两个,相加再加上第个结点更新答案。
一共就这两种情况。
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define RFOR(i,a,b) for(int i=a;i>=b;i--)
#define sf(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 200050+500;
const ll mod = 1e9+7;
int dp[maxn][10];
map<pair<int,int>,int>mp;
vector<int>ver[maxn],G[maxn];
int A[maxn],ans=0;
int Mx1[20],Mx2[20];
void dfs(int u,int f){
for(auto v:G[u]){
if(v==f)continue;
dfs(v,u);
}
for(int i=1;i<=10;i++)Mx1[i]=Mx2[i]=0;
for(int i=1;i<=ver[u].size();i++){
dp[u][i]=1;
for(int j=0;j<G[u].size();j++){
int v=G[u][j];
if(v==f)continue;
int pos=mp[make_pair(A[v],ver[u][i-1])];
dp[u][i]=max(dp[u][i],dp[v][pos]+1);
if(dp[v][pos]>=Mx1[i])Mx2[i]=Mx1[i],Mx1[i]=dp[v][pos];
else if(dp[v][pos]>Mx2[i])Mx2[i]=dp[v][pos];
}
}
for(int i=1;i<=ver[u].size();i++){
ans=max(ans,dp[u][i]);
ans=max(ans,Mx1[i]+Mx2[i]+1);
}
}
int main(){
int n;cin>>n;
FOR(i,1,n)sf(A[i]);
FOR(i,1,n-1){
int u,v;
sf(u),sf(v);
G[u].push_back(v);
G[v].push_back(u);
}
for(int i=1;i<=n;i++){
int val=A[i];
for(int j=2;j<=sqrt(val);j++){
if(val%j==0){
ver[i].push_back(j);
while(val%j==0)val/=j;
mp[make_pair(A[i],j)]=ver[i].size();
}
}
if(val!=1){
ver[i].push_back(val);
mp[make_pair(A[i],val)]=ver[i].size();
}
// for(auto v:ver[i])cout<<v<<" ";puts("");
}
dfs(1,-1);
cout<<ans<<endl;
}
F
题意
辆车,起点、终点、耗油量、最多加油次数。
个地点,位置。
求最小油箱使得车都能在限制内到达。
题解
显然求出每辆车最多耗油即可,对于每辆车最多耗油去掉也就是最多路径长。
如果能加油次,就是把总路程切成段,里面最长的那段。
然后再取最大值即是答案。
表示到切成段中的最长段长度。
容易发现,我们必须去掉一个.
前者随着变大,后者则变小。初始前者是
所以一开始是后者,然后是前者。
也就是只有两个决策点。
并且随着增大,前者和后者最多同时加上新的一段,前者可能会加的更小。
所以能保证,到达决策点后,之后,决策点也在往前。
这是可以单调的。
#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define sf(x) scanf("%d",&x)
using namespace std;
typedef long long ll;
const int maxn = 250050;
int n,m;
int dp[403][403][403],p[401];
int s[maxn],t[maxn],c[maxn],r[maxn];
int main(){
cin>>n>>m;
FOR(i,1,n)sf(p[i]);
FOR(i,1,m){
sf(s[i]),sf(t[i]);
sf(c[i]),sf(r[i]);
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
dp[i][j][1]=p[j]-p[i];
}
}
for(int k=2;k<=n+1;k++){
for(int i=1;i<=n;i++){
int pos=i;
for(int j=i+1;j<=n;j++){
while(pos<=j&&dp[i][pos][k-1]<p[j]-p[pos])pos++;
dp[i][j][k]=min(p[j]-p[pos-1],dp[i][pos][k-1]);
}
}
}
ll ans=0,tmp;
for(int i=1;i<=m;i++){
tmp=1ll*c[i]*dp[s[i]][t[i]][r[i]+1];
ans=max(ans,tmp);
}
cout<<ans<<endl;
}
来源:CSDN
作者:mxYlulu
链接:https://blog.csdn.net/mxYlulu/article/details/104117505