題目描述考慮將沒有出現的血量集合 \(m_i\) 從小到大排序,觀察發現對於每乙個 \(m_i\) ,其會使得所有血量 \(-m_i\)小豆喜歡玩遊戲,現在他在玩乙個遊戲遇到這樣的場面,每個怪的血量為 \(a_i\) ,且每個怪物血量均不相同, 小豆手裡有無限張「褻瀆」。
褻瀆的效果是對所有的怪造成 \(1\) 點傷害,如果有怪死亡,則再次施放該法術。我們認為血量為 \(0\) 的怪物死亡。
小豆使用一張「褻瀆」會獲得一定的分數,分數計算如下,在使用一張「褻瀆」之後,每乙個被褻瀆造成傷害的怪會產生 \(x^k\) ,其中 \(x\) 是造成傷害前怪的血量為 \(x\) 和需要殺死所有怪物所需的「褻瀆」的張數 \(k\) 。
\(n \leq 1000, k \leq 15\)
設此時場上的最大血量為 \(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 顯然可以直接維護未出...