洛谷 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;
}