HDU 5145 分塊 莫隊

2022-05-20 10:32:01 字數 1528 閱讀 8822

給定n個數,q個詢問[l,r]區間,每次詢問該區間的全排列多少種。

數值都是30000規模

首先考慮計算全排列,由於有同種元素存在,相當於每次在len=r-l+1長度的空格隨意放入某種元素即$\binom$,那麼下種元素即為$\binom$,以此類推,直至最後直接填滿,那麼全排列為$}$

然後可以發現可以直接o(1)求得左右相鄰區間的值(就是乘或除),那麼考慮分塊莫隊。

/** @date    : 2017-09-23 18:57:10

* @filename: hdu 5145 分塊 莫隊.cpp

* @platform: windows

* @author : lweleth ([email protected])

* @link :

* @version : $id$

*/#include #define ll long long

#define pii pair#define mp(x, y) make_pair((x),(y))

#define fi first

#define se second

#define pb(x) push_back((x))

#define mmg(x) memset((x), -1,sizeof(x))

#define mmf(x) memset((x),0,sizeof(x))

#define mmi(x) memset((x), inf, sizeof(x))

using namespace std;

const int inf = 0x3f3f3f3f;

const int n = 1e5+20;

const double eps = 1e-8;

const ll mod = 1e9 + 7;

int k[30010];

int a[30010];

int blc[30010];

ll fac[30010];

ll inv[30010];

ll res[30010];

struct yuu

b[30010];

int cmp(yuu a, yuu b)

void init()

}int main()

sort(b + 1, b + 1 + q, cmp);

mmf(k);

ll l = 1, r = 0;

ll ans = 1, cnt = 0;

for(int i = 1; i <= q; i++)

while(l > b[i].l)

while(r > b[i].r)

while(l < b[i].l)

while(ans < 0)

ans += mod;

res[b[i].m] = ans;

} for(int i = 1; i <= q; i++)

printf("%lld\n", res[i]);

} return 0;

}

hdu5145(莫隊演算法 組合數逆元)

題意 乙個人有n個女朋友,每個女朋友都有乙個班級a i 現有m個詢問。每個詢問有乙個區間範圍 l,r 表示這個人想要約 l,r 範圍內的女生有幾種約法。第l個女生到第r個女生的區間,而不是班級 分析 給出公式,對於範圍 l,r 來說可能的情況為 r l 1 num x1 num x2 num xn ...

HDU1754 分塊入門1

題意 單點更新,區間求最值 思路 維護每個值 and 分塊,維護每塊的最值 如果 x 和 y 隸屬於同一塊,那麼直接列舉就行 如果它們不在同一塊,那麼中間的每一塊的最大值可以由數列 p 得到,其他x,y各自所在塊包含的元素直接列舉即可 列舉塊數複雜度 sqrt n 列舉塊內元素複雜度 sqrt n ...

HDU 4389 (分塊打表)

題意 f x 表示x的各數字的和,給出 l,r 問區間中有多少個數x,存在x mod f x 0 思路 l,r範圍在1e9,估算複雜度後發現應該可以遞推打出乙個表,按1000000每塊,分塊後將塊內答案儲存在陣列中,塊間累加,塊內暴力,查詢即可。好像正解是數字dp include include i...