题目1 : hohahola
二分
package l601;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n=sc.nextInt(),x=sc.nextInt(),y=sc.nextInt(),z=sc.nextInt();
long lo=0,hi=n;
while(lo+1=y) return n*z>=mid*x;
return (x-y)*mid<=z*(n-mid);
}
}
题目2 : 最大顺子
比赛思路是DP,但是MLE
答案是遍历数组,考虑以当前位置的数开始能不能做成顺子,至于能不能就二分
package l602;
import java.util.Arrays;
import java.util.Scanner;
public class Copy_3_of_Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt(),k=sc.nextInt();
int[]a=new int[n];
for(int i=0;i=(a[i]-a[i-1]-1))
dp1[i][j] = dp1[i-1][j-(a[i]-a[i-1]-1)];
else
dp1[i][j] = a[i]-j;
}
}
int res=-1;
int[]dp21=new int[m+1], dp22=new int[m+1];
for(int j=0;j<=m;j++) {
dp21[j]=a[n-1]+j;
int left = dp1[n-1][m-j], right=dp21[j];
if(right-left+1>=k)
res=Math.max(res, right);
}
for(int i=n-2;i>=0;i--) {
for(int j=0;j<=m;j++) {
if(j>=(a[i+1]-a[i]-1))
dp22[j] = dp21[j-(a[i+1]-a[i]-1)];
else
dp22[j] = a[i]+j;
}
for(int j=0;j<=m;j++) {
int left = dp1[i][m-j], right=dp22[j];
if(right-left+1>=k)
res=Math.max(res, right);
}
int[] tmp=dp21;
dp21=dp22;
dp22=tmp;
}
System.out.println(res);
}
}
package l602;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt(),k=sc.nextInt();
int[]a=new int[n];
for(int i=0;i=k) res=Math.max(res, a[i]+k-1);
}
System.out.println(res);
}
}
题目3 : 路径包含问题
思路就是先求LCA,判断一个是不是另外一个的root,然后分类讨论
可能是因为数字版的dfs,所以下一次就感觉有点难,其实如果熟悉了数字版的,这就跟树的遍历一样。
因为是数字,其实还更好求LCA这些,我是记录path,然后复制试一下,但是这样MLE了,别人是先构造好数组,然后控制index直接填,可能更高效。搞OI的人还是太屌了
package l603;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt();
List[]ms=new List[n+1];
for(int i=1;i<=n;i++) ms[i]=new ArrayList();
for(int i=1;i[]paths=new List[n+1];
Listpath=new ArrayList();
path.add(1);
dfs(1, 0, sz, dep, ms, paths, path);
while(m-->0) {
int a=sc.nextInt(),b=sc.nextInt();
int lca = getLCA(paths[a], paths[b]);
if(lca==a) System.out.println(sz[b]*(n-sz[getExtra(paths[b], a)]));
else if(lca==b) System.out.println(sz[a]*(n-sz[getExtra(paths[a], b)]));
else System.out.println(sz[a]*sz[b]);
}
}
private static int getExtra(List l, int b) {
int i=0;
while(l.get(i)!=b) i++;
return l.get(i+1);
}
private static int getLCA(List a, List b) {
int i=0;
for(;i[] ms, List[] paths, List path) {
paths[x]=new ArrayList(path);
sz[x]=1;
dep[x]=d;
for(int i=0;i
#include
using namespace std;
const int maxn=1e5+10,mod=323232323,inf=0x3f3f3f3f;
int n,m,k,t,fa[20][maxn],sz[maxn],dep[maxn],last;
vectore[maxn];
void dfs(int x,int y=0)
{
dep[x]=dep[y]+1;
for(int i=1;fa[i-1][fa[i-1][x]];++i)
fa[i][x]=fa[i-1][fa[i-1][x]];
sz[x]=1;
for(auto z:e[x])
{
if(z==y)continue;
fa[0][z]=x;
dfs(z,x);
sz[x]+=sz[z];
}
}
int lca(int x,int y)
{
if(dep[x]>dep[y])
swap(x,y);
for(int i=19;i>=0;i--)
{
if(dep[fa[i][y]]>dep[x])
y=fa[i][y];
}
if(fa[0][y]==x)
{
last=y;
return x;
}
if(dep[fa[0][y]]>=dep[x])
y=fa[0][y];
for(int i=19;i>=0;i--)
{
if(fa[i][x]!=fa[i][y])
x=fa[i][x],
y=fa[i][y];
}
return fa[0][x];
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
for(i=2;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
dfs(1);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
int fa=lca(x,y);
if(fa==x)
printf("%lld\n",(long long)(n-sz[last])*sz[y]);
else if(fa==y)
printf("%lld\n",(long long)(n-sz[last])*sz[x]);
else printf("%lld\n",(long long)sz[x]*sz[y]);
}
return 0;
}