洛谷 11 月月赛 II div.2 T2&T3 题解

T2

P7107 天选之人
https://www.luogu.com.cn/problem/P7107?contestId=13515

根据贪心,那p个人最多各能拿到p/k个有记号的纸团

如果p/k>m不就爆0了???!!!

所以要判一下

于是得到了判断YES/NO的语句(能用乘法绝对不用除法,不然就可以开心地爆0了)(av是平均的意思...)
(n - p) * (av - 1) >= k - av * p

然后就是YES的输出啦

p个人抽到了av张,然下的人能尽量拿av-1张,如果剩余的不够了,拿掉剩下的,其余的人拿0张

#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define int long long
#define re register
#define mod 998244353
#define inf 0x3f3f3f3f
using namespace std;
const int N=300005;
int n,m,k,d,t,sum,mi,p;  
char a[N];
int b[N];
template <class T> inline void read(T &x){
	x=0;int g=1; char s=getchar();
	for (;s>'9'||s<'0';s=getchar())	if (s=='-') g=-1;
	for (;s<='9'&&s>='0';s=getchar()) x=(x<<1)+(x<<3)+(s^48);
	x*=g;
}
signed main()
{
	re int i,j,x,y,z;
	read(n);read(m);read(k);read(p);
	if(n==p&&k%p!=0) return printf("NO"),0;
	int av=k/p;
	
	if (av>m) av=m;
	int tmp=k-av*p,cnt=0;
	if ((n - p) * (av - 1) >= k - av * p)//av>ceil(tmp*1.0/(n-p) ??????//////(n - p) * (av - 1) >= k - av * p
	{
		printf("YES\n");
		for (i=1;i<=p;i++)
			printf("%lld %lld\n",av,m-av);
		
		while(tmp)
		{
			if (tmp>=av-1) printf("%lld %lld\n",av-1,m-av+1),tmp-=av-1;
			else printf("%lld %lld\n",tmp,m-tmp),tmp=0;
			cnt++;
		}
		for (i=1;i<=n-p-cnt;i++)
			printf("%lld %lld\n",0,m);
	}
	else printf("NO");
	return 0;
}

T3

P7108 移花接木
https://www.luogu.com.cn/problem/P7107?contestId=13515

对a,b的大小进行讨论

当a<=b时,因为要删掉的操作一定多余接上的操作,所以可以把一些删掉的接上去算作一步,所以答案是a*(b的h次方)

当a>b时,不仅h+1层的节点都要删,第0层有b的0次方个节点,共有1(a-b)个要删除的儿子,第1层有b的1次方个节点,共有b(a-b)个要删除的儿子...第h-1层有b的h-1次方个节点,共有(b的h-1次方)*(a-b)个要删除的儿子

然后用等比数列求和逆元做

注意:公比是1的数列不能用公式,否则100pts-->30pts

#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define int long long
#define re register
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
const int N=300005;
int n,m,k,d,t,p,h,a,b;  

int poww(int x,int y)
{
	int tmp=1;
	for (;y;x=x*x%mod,y>>=1)
	if (y&1) tmp=tmp*x%mod;
	return tmp; 
}
int ny(int x)
{
	return poww(x,mod-2);
}
template <class T> inline void read(T &x){
	x=0;int g=1; char s=getchar();
	for (;s>'9'||s<'0';s=getchar())	if (s=='-') g=-1;
	for (;s<='9'&&s>='0';s=getchar()) x=(x<<1)+(x<<3)+(s^48);
	x*=g;
}
signed main()
{
	re int i,j,x,y,z;
	read(t);
	while(t--)
	{
		read(a);read(b);read(h);
		int tmp=poww(b,h);
		if (a>b)
		{
			if(b==1)
			printf("%lld\n",((a-b)*h%mod+a*tmp%mod)%mod);
			else
			printf("%lld\n",((a-b)*(tmp-1)%mod*ny(b-1)%mod+a*tmp%mod)%mod);
		}
		else
			printf("%lld\n",a*tmp%mod);
	}
	return 0;
}                  

posted @ 2020-11-29 20:25  Ritalc  阅读(112)  评论(0编辑  收藏  举报