……去年去考D2似乎只有二十分来着……【捂脸
于是今天晚上就补补进度【
T1:二分答案【去年不会于是写的贪心【跪地
#include<bits/stdc++.h>
#define MAXN 50005
using namespace std; int l,n,m;
int a[MAXN];
bool check(int x){
for(int pre = 0,cnt = 0,i = 1;i<=n;++i){
if(a[i] - a[i-1] + pre < x) ++cnt , pre = a[i] - a[i-1] + pre;
else pre = 0;
if(cnt>m) return 0;
}
return 1;
}
int main(){
scanf("%d%d%d",&l,&n,&m);
a[++n] = l;
for(int i=1;i<n;++i) scanf("%d",a+i);
int L = 0 , R = l;
while(L^R){
int mid = ((L+R)>>1)+1;
if(check(mid)) L = mid;
else R = mid-1;
}
printf("%d",L);
return 0;
}
T2:O(n*m*k)的dp,滚动一下优化空间,f[i][j][k][0..1]表示a串匹配到第i个字符,b串匹配到第j个字符,已经分了k段,第i个字符选不选(因为在转移到f[i+1][j+1][k][0..1]的时候必须连续才合法)【对不起代码写的丑23333强行增加代码长度
#include<bits/stdc++.h>
#define MAXN 1005
#define MAXM 205
#define MAXK 205
#define MOD 1000000007
using namespace std; int n,m,K;
int f[2][MAXM][MAXK][2];
char a[MAXN],b[MAXM];
int main(){
scanf("%d%d%d%s%s",&n,&m,&K,a+1,b+1);
// f[0][0][0][0] = f[0][0][0][1] = f[1][0][0][0] = f[1][0][0][1] = 1;
f[0][0][0][1] = f[1][0][0][1] = 1;
for(int now=1,i=1;now<=n;i=(++now)&1){
for(int j=1;j<=min(now,m);++j){
for(int k=1;k<=K;++k){
if(a[now]==b[j]){
(f[i][j][k][1] += f[i^1][j-1][k][1]) %= MOD;
(f[i][j][k][1] += f[i^1][j-1][k-1][0]) %= MOD;
(f[i][j][k][1] += f[i^1][j-1][k-1][1]) %= MOD;
(f[i][j][k][0] += f[i^1][j][k][1]) %= MOD;
(f[i][j][k][0] += f[i^1][j][k][0]) %= MOD;
}
else{
(f[i][j][k][0] += f[i^1][j][k][0]) %= MOD;
(f[i][j][k][0] += f[i^1][j][k][1]) %= MOD;
}
}
}
memset(f[i^1],0,sizeof f[i^1]);
// f[i^1][0][0][0] = f[i^1][0][0][1] = 1;
f[i^1][0][0][1] = 1;
}
printf("%d",(f[n&1][m][K][0]+f[n&1][m][K][1])%MOD);
return 0;
}
T3:……听说可以O(n)【因为删除的路径肯定在最长链上,于是就变成了一条链上挂着树,瞎搞搞扫过去】我等蒟蒻还是默默地带log吧23333
先预处理每个询问的LCA,最长的最短肯定二分答案,在记录的时候直接在两个端点和LCA上打标机,最后按照dfs序倒着更新,显然可以O(n)找到所有链的交,如果交集为空显然不合法,再check删掉交集里最长的边是否合法,好写好调【无视一些没有使用的数组嘛2333
#include<bits/stdc++.h>
#define MAXN 300005
using namespace std; int n,m;
//=================================================
inline int read(){
char ch = getchar();
while(!isdigit(ch)) ch = getchar();
int rtn = 0;
while(isdigit(ch)) rtn = rtn*10 +ch-'0' , ch = getchar();
return rtn;
}
//=================================================
int root = 20000218;
struct t1{
int to,nxt,lth;
}edge[MAXN<<1]; int cnt_edge = 0;
int fst[MAXN];
void addedge(int x,int y,int l){
edge[++cnt_edge].to = y;
edge[cnt_edge].nxt = fst[x];
edge[cnt_edge].lth = l;
fst[x] = cnt_edge;
edge[++cnt_edge].to = x;
edge[cnt_edge].nxt = fst[y];
edge[cnt_edge].lth = l;
fst[y] = cnt_edge;
}
int dfn[MAXN],idf[MAXN],cnt_dfs;
int fth[MAXN],dpt[MAXN],dis[MAXN];
int siz[MAXN],top[MAXN],son[MAXN];
int dd[MAXN];
void dfs1(int now){
siz[now] = 1;
for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
int aim = edge[tmp].to;
if(aim==fth[now]) continue;
fth[aim] = now;
dpt[aim] = dpt[now]+1;
dis[aim] = dis[now] + edge[tmp].lth;
dd[aim] = edge[tmp].lth;
dfs1(aim);
siz[now] += siz[aim];
if(siz[aim] > siz[son[now]]) son[now] = aim;
}
}
void dfs2(int now,int tp){
top[now] = tp;
dfn[now] = ++cnt_dfs;
idf[cnt_dfs] = now;
if(son[now]) dfs2(son[now],tp);
for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
int aim = edge[tmp].to;
if(aim==fth[now]||aim==son[now]) continue;
dfs2(aim,aim);
}
}
struct t2{
int lth,lca;
int u,v;
bool operator < (const t2 &ano) const{
return lth < ano.lth;
}
}Q[MAXN];
int LCA(int x,int y){
while(top[x]^top[y]){
if(dpt[fth[top[x]]] < dpt[fth[top[y]]]) swap(x,y);
x = fth[top[x]];
}
return dpt[x]<dpt[y]?x:y;
}
int tag[MAXN];
inline bool sol(int x){
memset(tag,0,sizeof tag);
int cnt = 0 , LONG = 0;
for(int i=1;i<=m;++i)
if(Q[i].lth>x)
++tag[Q[i].u] , ++tag[Q[i].v] , tag[Q[i].lca]-=2 , ++cnt , LONG = max(LONG,Q[i].lth);
if(!cnt) return 1;
int mx = -1;
for(int i=n;i;--i){
int x = idf[i];
tag[fth[x]] += tag[x];
if(tag[x]==cnt) mx = max(mx,dd[x]);
}
if(!~mx) return 0;
if(LONG - mx > x) return 0;
return 1;
}
inline void work(){
int L = 0 , R = n*1000;
while(L^R){
int mid = (L+R)>>1;
if(sol(mid)) R = mid;
else L = mid+1;
}
printf("%d\n",L);
}
int read_x,read_y,read_l;
int main(){
n = read() , m = read();
(root%=n)++;
for(int i=1;i<n;++i){
read_x = read() , read_y = read() , read_l = read();
addedge(read_x,read_y,read_l);
}
dpt[root] = 1;
dfs1(root);dfs2(root,root);
for(int i=1;i<=m;++i){
Q[i].u = read() , Q[i].v = read();
Q[i].lca = LCA(Q[i].u,Q[i].v);
Q[i].lth = dis[Q[i].u] + dis[Q[i].v] - (dis[Q[i].lca]<<1);
}
work();
return 0;
}