TJOI 2018 教科書般的褻瀆

2022-03-31 17:18:08 字數 1250 閱讀 7723

題目描述

小豆喜歡玩遊戲,現在他在玩乙個遊戲遇到這樣的場面,每個怪的血量為 \(a_i\) ,且每個怪物血量均不相同, 小豆手裡有無限張「褻瀆」。

褻瀆的效果是對所有的怪造成 \(1\) 點傷害,如果有怪死亡,則再次施放該法術。我們認為血量為 \(0\) 的怪物死亡。

小豆使用一張「褻瀆」會獲得一定的分數,分數計算如下,在使用一張「褻瀆」之後,每乙個被褻瀆造成傷害的怪會產生 \(x^k\) ,其中 \(x\) 是造成傷害前怪的血量為 \(x\) 和需要殺死所有怪物所需的「褻瀆」的張數 \(k\) 。

\(n \leq 1000, k \leq 15\)

考慮將沒有出現的血量集合 \(m_i\) 從小到大排序,觀察發現對於每乙個 \(m_i\) ,其會使得所有血量 \(-m_i\)

設此時場上的最大血量為 \(c\) ,那麼其能產生的貢獻就是 \((\sum_^ j^k) - \sum_^ m_i\ ^k\)

由於 \(m\) 很小,計算後面式子的複雜度可以忽略不計,問題就轉化為快速計算前面的式子

觀察發現前面的式子其實就是乙個 \(k + 1\) 次的多項式,暴力插值求解即可

/*program by mangoyang*/

#include#define inf (0x7f7f7f7f)

#define max(a, b) ((a) > (b) ? (a) : (b))

#define min(a, b) ((a) < (b) ? (a) : (b))

typedef long long ll;

using namespace std;

template inline void read(t &x)

#define int ll

const int mod = 1000000007;

vectorx, y;

int a[105], n, m;

inline int pow(int a, int b)

inline void prework(int k)

inline int calc(int now)

return res;

}inline void solve()

(ans += calc(n - now)) %= mod;

cout << ((ans % mod) + mod) % mod << endl;

}signed main()

TJOI2018 教科書般的褻瀆

點此看題 首先問題可以轉化成求 i 1nim sum n i m i 1n im0x01 拉格朗日插值法 你會發現這就是板子,因為他是乙個m 1 m 1m 1次多項式,選m 2 m 2m 2個點插值就可以了。時間複雜度o m 3 o m 3 o m3 考試時候降智寫了o m 4 o m 4 o m4...

TJOI2018 教科書般的褻瀆

首先,認真讀題不難發現若血量的區間 1,m i 連續,則只需要一張褻瀆就可以殺死區間 1,m i 內所有怪物,所以 k m 1 考慮到這點,我們就可以輕鬆的寫出式子 保證 a i 公升序 定義 a 0 0 有 large ans sum limits left sum limits j sum li...

Code 7 教科書般的褻瀆

不難發現,對於所有血量的隨從都存在的情況,詢問 1,m 1,m 1,m 的答案應為 o n logn o nlogn o nlog n 級別。考慮分別維護 f if i fi 表示 i ii 點法術傷害的褻瀆造成傷害的次數。對於 i o n i leq o sqrt i o n 顯然可以直接維護未出...