[规律]JZOJ 4222 恐怖的奴隶主
分析
看到题目就想到:所有人,都过来*n
然后比赛最后开暴力打表,发现了神奇的循环节,但是并没有发现规律
首先我们需要知道循环节是从什么时候开始:当某一时刻奴隶主(包括将死的)爆满时,下一时刻循环节开始
然后%%%WHH大爷发现了循环节神奇的规律:
当j=i%m+1(如果小于循环节开始位置就再加m+1)大于m s[i]=k-s[j-m]
否则直接为k
鬼知道为什么,但是知道循环节开始位置如果小于等于m=1的话就全部补0,那也就是k了,这样减少时空复杂度
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; const int N=1e4+10; ll n,m,k,q[N],s[N],cycle; int main() { scanf("%lld%lld%lld",&n,&m,&k); if (n==0) { printf("1\n"); return 0; } if (m==1) { printf("0\n"); return 0; } q[0]=s[0]=1; for (int i=1;i<=n;i++) { q[i]=min(k-s[i-1],s[i-1]-(i>=m?q[i-m]:0)); s[i]=s[i-1]+q[i]-(i>=m?q[i-m]:0); if (q[i]+s[i-1]==k) { cycle=i;break; } } if (cycle==n||!cycle) { printf("%lld\n",s[n]); return 0; } n=n%(m+1);if (n<=cycle) n+=m+1; printf("%lld\n",k-(n>=m?q[n-m]:0)); }
在日渐沉没的世界里,我发现了你。