description
在《炉石传说》这款游戏中,有一张随从卡牌叫做“恐怖的奴隶主”。这张卡牌的描述是这样的:每当该随从受到伤害且没有死亡,召唤另一个恐怖的奴隶主。还有一张卡牌叫做“旋风斩”,描述是“对所有随从造成1点伤害”。使用“旋风斩”后,生命值变为0的“恐怖的奴隶主”并不会立即死亡,而会先结算召唤新的“恐怖的奴隶主”再结算生命值为0的“恐怖的奴隶主”的死亡。当然,使用旋风斩后,生命值变为0的“恐怖的奴隶主”不会召唤新的“恐怖的奴隶主”。随从的数量是有上限的,在召唤一个随从前如果随从数量已经达到上限则不会召唤。现在,如果随从数量上限为k,最开始只有一个生命值为m的“恐怖的奴隶主”,而且新召唤出来的“恐怖的奴隶主”的生命值也是m,那么使用了n张“旋风斩”后还有多少个“恐怖的奴隶主”呢?
analysis
-
打表找规律
-
252525分左右可以用数组和滚动指针来弄
-
如果手动模拟数据,可以发现开始以222的次幂增加
-
当kkk被填满时,开始出现循环节,后面的和前面一样了
-
此时nnn直接变成nmod(m+1)n mod(m+1)nmod(m+1),模拟前面的一部分,直接输出即可
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define MAXN 10005
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))
using namespace std;
ll a[MAXN];
ll n,m,k,ans,t=1;
O3 inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
O3 inline void print(ll x)
{
printf("%lld\n",x);
exit(0);
}
O3 int main()
{
//freopen("T3.in","r",stdin);
n=read(),m=read(),k=read();
if (m<=1)print(0);
fo(i,1,m-1)
{
a[i]=t,t<<=1;
if (t>k)
{
ans=i-2,t>>=1;
break;
}
if (i==n)print(t);
}
if (n<m)print(k);
n=(n-ans)%(m+1);
if (n==0)n=m+1;
if (n==1)print(t);
if (n<=m-ans-2)print(k);
if (n>=m-ans+2)print(k-a[n-(m-ans)]);
print(k-1);
return 0;
}