# 6.12联考题解

A：

$O\left(n\sqrt{n}\right)$$O(n\sqrt n)$

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define ld long double
using namespace std;

{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 210000;

int n,m;
int val[maxn];
ll sum[600][600]; int N;

int T,k,d;
int t[maxn];

int main()
{
freopen("lzz.in","r",stdin);
freopen("lzz.out","w",stdout);

for(int i=1;i<=n;i++)
{
for(int j=1;j<=N;j++) sum[j][i%j]+=val[i];
}
while(m--)
{
if(type==1)
{
for(int j=1;j<=N;j++) sum[j][x%j]+=y-val[x];
val[x]=y;
}
else
{
if(T==1&&d<=N) { printf("%.4Lf\n",(ld)sum[d][k%d]); continue; }

int mnc=t[1]; for(int i=2;i<=T;i++) mnc=min(mnc,t[i]);
ld ans=val[k];
ld p=1.0;
for(int i=1;i<=200;i++)
{
int x=k+i*d; if(x>n||i>mnc) break;
p=p*((ld)(mnc-i+1)/(n-i));
ans+=p*val[x];
}
p=1.0;
for(int i=1;i<=200;i++)
{
int x=k-i*d; if(x<1||i>mnc) break;
p=p*((ld)(mnc-i+1)/(n-i));
ans+=p*val[x];
}
printf("%.4Lf\n",ans);
}
}

return 0;
}


B：

$f\left[i\right]\left[j\right]\left[0/1\right]$$f[i][j][0/1]$表示$i$$i$的子树里有$j$$j$条链，$i$$i$向上的父边是否被链占用，最大价值

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

inline void up(int &a,const int &b){if(a<b)a=b;}
const int maxn = 2100;

int n,K,C;
struct edge{int y,c,nex;}a[maxn<<1]; int len,fir[maxn];
inline void ins(const int x,const int y,const int c){a[++len]=(edge){y,c,fir[x]};fir[x]=len;}

int siz[maxn];
int f[maxn][maxn][2],g[maxn][2];
void dp(int x,int fa)
{
siz[x]=1;
f[x][0][0]=0,f[x][0][1]=0;
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(y!=fa)
{
dp(y,x);
for(int j=0;j<=siz[x]+siz[y]&&j<=K;j++) g[j][0]=g[j][1]=0;
for(int j=0;j<=siz[x];j++) for(int l=0;l<=siz[y]&&j+l<=K;l++)
{
up(g[j+l][0],f[x][j][0]+f[y][l][0]);
up(g[j+l][1],f[x][j][0]+f[y][l][1]+a[k].c);
up(g[j+l][1],f[x][j][1]+f[y][l][0]);
up(g[j+l+1][0],f[x][j][1]+f[y][l][1]+a[k].c-C);
}
siz[x]+=siz[y];
for(int j=0;j<=siz[x]&&j<=K;j++) f[x][j][0]=g[j][0],f[x][j][1]=g[j][1];
}
}

int main()
{
freopen("mzz.in","r",stdin);
freopen("mzz.out","w",stdout);

while(scanf("%d%d%d",&n,&K,&C)!=EOF)
{
memset(fir,0,sizeof fir); len=0;
int sum=0;
for(int i=1;i<n;i++)
{
int x,y,c; scanf("%d%d%d",&x,&y,&c); x++,y++;
ins(x,y,c); ins(y,x,c);
sum+=c<<1;
}
for(int i=1;i<=n;i++) for(int j=0;j<=K;j++) f[i][j][0]=f[i][j][1]=0;
dp(1,0);
int ans=0;
for(int i=0;i<=K;i++) up(ans,f[1][i][0]);
printf("%d\n",sum-ans);
}

return 0;
}


C：

……

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120