珂朵莉給你乙個長為n的序列,有m次查詢
每次查詢給兩個數l,r
設s為區間[l,r]內所有數的乘積
求s的約數個數mod 1000000007
輸入描述:
第一行兩個正整數n,m
第二行乙個長為n的序列
之後m行每行兩個數l和r
輸出描述:
對於每個詢問,輸出乙個整數表示答案
示例1輸入
複製
5564
218910015
2423
1434
輸出
複製
165159
4510
備註:
對於100%的資料,有n , m <= 100000 , a[i] <= 1000000
莫隊+數論(約數個數)
很容易看出是莫隊的題,個人認為難點在於求約數的個數,常規的求約束的個數肯定不行,有乙個叫約束個數定理的東西
任何乙個大於1的n都可以分解:
n=p1a1×p2a2×p3a3*…*pkak,p為素數
而n的約數的個數就是(a1+1)(a2+1)(a3+1)…(ak+1)
再看一下本題資料,對於不超過1000的素數我們可以直接維護每個素數的冪指數+1的字首乘積(共168個),而超過1000的素因數最多也就乙個。**中ant用來記錄1000之外的素因子,res用來記錄1000之內的每個素數的冪指數+ 1 +1+1的字首乘積
線性篩就是每一次被最小素因數給篩出來,所以用線性篩來計算因數和。因為題目要mod,所以我們還要線性預處理逆元,方便後面使用
nv[0]
= inv[1]
=1;for
(int i=
2;i<=n+
1;i++
) inv[i]
=1ll
*(mod-mod/i)
*inv[mod%i]
%mod ;
具體線性篩如何求因數和可以看其他部落格講解
具體**如下
#include
using
namespace std;
typedef
long
long ll;
const
int n =
1e5+10;
const
int mod =
1e9+7;
int prime[
1007
],tot;
bool vis[
1007];
ll inv[n]
,ans[n]
,ant;
int be[n]
,a[n]
,sum[n*10]
,pre[n]
[170];
// sum存 在區間內 > 1000 的素數的個數
void
init()
}struct moq[n]
;int
cmp(mo a,mo b)
void
add(
int pos)
void
del(
int pos)
intmain()
}}for(
int i =
1;i <= m;i++
)scanf
("%d%d"
,&q[i]
.l,&q[i]
.r),q[i]
.id = i;
sort
(q+1
,q+m+
1,cmp)
;memset
(sum,0,
sizeof
(sum));
ant =1;
int l =
1,r =0;
for(
int i =
1;i <= m;i++
)for
(int i =
1;i <= m;i++
)printf
("%lld\n"
,ans[i]);
return0;
}
珂朵莉與失憶 SDUT
time limit 1000 ms memory limit 65536 kib submit statistic problem description 珂朵莉由於受到前世記憶的侵蝕會不斷地失憶。但是並不是每天都會失憶。失憶的發生條件是當且僅當這一天的編號為素數的時候,會失去這一天編號的數字之和...
珂朵莉樹學習筆記
珂朵莉樹是一種基於 set 的暴力資料結構,真的很好懂 因為暴力鴨 又叫 old driver tree 老司機樹 適用於區間賦值,資料隨機.首先來講講它的思想,它把區間 1,n 分成若干個 l i,r i l i,r i 內的數都一樣,為 w i 舉栗子 區間 1,5 的初值為 1 現在只有乙個區...
珂朵莉的值域連續段
珂朵莉的值域連續段 時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 題目描述 珂朵莉給你乙個有根樹,求有多少個子樹滿足其內部節點編號在值域上連續 一些數在值域上連續的意思即其在值域上構成乙個連續的區間 輸入描述 ...