首页 > 其他分享 >8.18

8.18

时间:2022-08-18 20:55:47浏览次数:49  
标签:rll ch ll maxn 8.18 mod define

下发文件和题解

T1 接力比赛

既然要求取小白与小黑班级总 值相等时总 的最大值,那么这就可以转化为最简单的 背包问题.

分别表示小黑和小白班级中 值为 的最大值.

枚举 获得 ,那么转移显然:

然后扫一遍查询一下和的最大值即可.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define sort random_shuffle // Shiyiming的梗
#define rll rg ll
#define maxn 1000001
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
struct node
{
	ll w,v;
}a[maxn],b[maxn];
ll n,m,mx,mmx,ans;
ll dp[2][maxn];
int main()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	memset(dp,-0x3f,sizeof(dp));
	n=read();m=read();
	for(rll i=1;i<=n;i++) a[i].w=read(),a[i].v=read();
	for(rll i=1;i<=m;i++) b[i].w=read(),b[i].v=read();
	sort(a+1,a+n+1);sort(b+1,b+m+1);
	mx=dp[0][0]=0;
	for(rll i=1;i<=n;i++)
		for(rll j=mx;j+1;j--)
		{
			if(dp[0][j+a[i].w]<dp[0][j]+a[i].v)
			{
				dp[0][j+a[i].w]=dp[0][j]+a[i].v;
				mx=max(mx,j+a[i].w);
			}
		}
	mmx=max(mmx,mx);
	mx=dp[1][0]=0;
	for(rll i=1;i<=m;i++)
		for(rll j=mx;j+1;j--)
		{
			if(dp[1][j+b[i].w]<dp[1][j]+b[i].v)
			{
				dp[1][j+b[i].w]=dp[1][j]+b[i].v;
				mx=max(mx,j+b[i].w);
			}
		}
	mmx=max(mmx,mx);
	for(rll i=1;i<=mmx;i++) if(dp[0][i]&&dp[1][i]) ans=max(ans,dp[0][i]+dp[1][i]);
	write(ans);
	return 0;
}

T2 树上竞技

由于按照点考虑并不好做,所以转移一下思路,按照边考虑.

对于一条边,如果它的两侧分别有 个点,我们可以设 ,那么最后的汇聚点一定是在 这个方向.

所以,可以设一条边的两侧分别有 个点,那么我们要求的答案即为:

.

为什么要取min?

因为我们要求的是最小代价,所以要在左子树和右子树中寻找价值最小的点数.

然后就是把 拆开:

.

m为偶数时的情况,可以通过一遍循环求出.

对于前面的部分,令 ,那么 .令 ,答案即为 .

对于 ,其实它的意义是从一个有 个物品的架子拿 个物品,前面 个物品中拿了 个的方案数.

如果要从 变成 ,发现答案变少的部分就是前面 个选了 个,而 也被选中了,只有这种情况会被 计算而不会被 计算.那么左右两种情况乘起来就是 .即:

.
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 2000001
#define mod 1000000007
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
ll n,m,k,ans;
vector<ll> g[maxn];
ll s[maxn],jc[maxn],ny[maxn],G[maxn];
bool fl[maxn];
static inline void dfs(rll x,rll fa)
{
	s[x]=1;
	for(rll i=0;i<g[x].size();i++)
	{
		rll to=g[x][i];if(to==fa) continue;
		dfs(to,x);s[x]+=s[to];
	}
}
static inline ll ksm(rll a,rll b)
{
	rll ans=1;a%=mod;
	for(rll i=b;i;i>>=1)
	{
		if(i&1) ans=ans*a%mod;
		a=a*a%mod;
	}
	return ans;
}
static inline ll C(rll n,rll m)
{
	if(n<m) return 0;
	return jc[n]*ny[m]%mod*ny[n-m]%mod;
}
int main()
{
	freopen("meeting.in","r",stdin);
	freopen("meeting.out","w",stdout);
	jc[0]=ny[0]=1;for(rll i=1;i<maxn;i++) jc[i]=jc[i-1]*i%mod;
	ny[maxn-1]=ksm(jc[maxn-1],mod-2);for(rll i=maxn-2;i;i--) ny[i]=ny[i+1]*(i+1)%mod;
	n=read();m=read();if(m==1) { puts("0"); return 0; }
	for(rll i=2,v;i<=n;i++) v=read(),g[i].push_back(v),g[v].push_back(i);
	dfs(1,0);
	if(!(m&1)) for(rll i=1;i<=n;i++) ans=(ans+C(s[i],m>>1)*((n-s[i]<0)?0:C(n-s[i],m>>1))%mod*(m>>1)%mod)%mod;
	k=m-1>>1;if(k) G[1]=C(n-1,m-1);
	for(rll i=1;i<=n;i++) G[i+1]=(G[i]-((i-1<0||k-1<0)?0:C(i-1,k-1))*((n-i-1<0||m-k-1<0)?0:C(n-i-1,m-k-1))%mod+mod)%mod;
	for(rll i=1;i<=n;i++) ans=(ans+(G[s[i]]*s[i]%mod+G[n-s[i]]*(n-s[i])%mod)%mod)%mod;
	write(ans);
	return 0;
}

标签:rll,ch,ll,maxn,8.18,mod,define
From: https://www.cnblogs.com/1Liu/p/16600055.html

相关文章

  • 8.18总结
    泡泡堂\(solution\)苹果树\(solution\)字符合并\(solution\)脑洞治疗仪\(solution\)万万没想到,我50pts的原因是数组没开够线段树维护修改操作,注意先挖后补ACCo......
  • 8.18集训
    回到了Luogu,继续刷COCI……上午事实证明后三题是可做题,前三题不大可做。T1P6405开始码了一个相邻的树木连边,边权设为相等的时间,然后点边互换跑连通块算大小,默认恒等......
  • NOIP2022模拟赛一 By RSJ 08.18
    A.「NOIP2022模拟赛一ByRSJ」StringSearchPro给定一个\(01\)字符串,查找一个子串使得\(0\)在这个子串中出现了\(\frac{p}{q}\cdotk\)次,其中\(k\)是子串长度\(n,p,q......