HDU5860 (遞推)

2022-08-05 16:03:14 字數 1487 閱讀 6146

problem death sequence

題目大意

排成一行的約瑟夫問題。

n個人排成一行,從第一個人開始,每個k個人報數,報到數的人被殺死,剩下的人重新排成一行再報數。

一共q個詢問,每次詢問第qi個死的人是誰。

n <= 3000000 , q <= 1000000 , k>=1 。

解題分析

顯然每一輪遊戲可以看做是一個子問題。

假設編號為0~n-1,若某輪中某人的編號為i,如果i被k整除則被殺,否則在下輪中編號為i-i/k-1。

dp[i]表示編號為i的人可以存活幾輪,那麼dp[i]=i % k ? dp[i-i/k-1] : 0 。

再用一個陣列s[i]記錄一下前i輪一共死了多少人。

這樣就可以在o(n)時間內預處理出一個答案序列。

參考程式

1 #include2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include

11 #include12 #include13

14using

namespace

std;

15 typedef long

long

ll;16 typedef unsigned long

long

ull;

1718

#define rep(i,k,n) for(int i=(k);i<=(n);i++)

19#define rep0(i,n) for(int i=0;i

20#define red(i,k,n) for(int i=(k);i>=(n);i--)

21#define sqr(x) ((x)*(x))

22#define clr(x,y) memset((x),(y),sizeof(x))

23#define pb push_back

24#define mod 1000000007

2526

const

int maxn=3000300;27

intn,k,q,tot;

28int

f[maxn],s[maxn],ans[maxn],a[maxn];

2930

void

init()

3141 f[0]=0

;42 rep(i,0,n-1

)46 rep(i,0,n-1)50

//rep(i,1,n) printf("%d %d\n",i,ans[i]+1 );51}

5253

intmain()

5466}67

68return0;

69 }

view code