給定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...