1493 D. GCD of an Array(map+multiset应用)
发布日期:2021-06-30 10:30:25 浏览次数:3 分类:技术文章

本文共 1607 字,大约阅读时间需要 5 分钟。

动态维护每一个质因子的最小值,相乘就是答案.

因为每次只乘上一个数,一个数的质因子最多只有 l o g ( n ) log(n) log(n)

所以整体质因子只有 n l o g ( n ) nlog(n) nlog(n)个,空间复杂度足够

我们可以开一个二维 m a p map map记作 m p [ i ] [ j ] mp[i][j] mp[i][j]表示 a [ i ] a[i] a[i]中有多少质因子 j j j

再开一个 m u l t i s e t multiset multiset记作 c n t [ i ] cnt[i] cnt[i]

c n t [ i ] cnt[i] cnt[i]里面的数是每个 a [ i ] a[i] a[i]拥有的质因子 i i i个数,如果质因子是 0 0 0就不插入了

那么如果 c n t [ i ] cnt[i] cnt[i]里有 n n n个数,说明所有的数都有 i i i这个质因子

那么 c n t [ i ] . b e g i n ( ) cnt[i].begin() cnt[i].begin()就是所有数中最少的 i i i的质因子, i c n t [ i ] . b e g i n ( ) i^{cnt[i].begin()} icnt[i].begin()就是质因子 i i i的贡献

所以每次插入 x x x,对 x x x分解质因子,动态维护 m p [ ] [ ] mp[][] mp[][],然后动态维护 c n t cnt cnt即可

主要是利用了 m u l t i s e t multiset multiset平衡树的特性,动态给数值排序第一个数最小

#include 
using namespace std;#define int long longconst int maxn = 3e5+10;const int mod = 1e9+7;map
mp[maxn];multiset
cnt[maxn];int nxt[maxn],n,q,ans=1;void add(int i,int x){
while( x!=1 ) {
int div = nxt[x], add = 0; while( nxt[x]==div ) add++, x=x/nxt[x]; int now = mp[i][div];//之前有多少div这个质因子 mp[i][div] += add; int mi = 0;//之前所有数的最小质因子数量 if( cnt[div].size()==n ) mi = (*cnt[div].begin() ); if( now ) cnt[div].erase( cnt[div].find(now) );//抹掉原来的因子 cnt[div].insert( now+add );//加上现在的因子 if( cnt[div].size()==n )//计算质因子的贡献 {
int mx = (*cnt[div].begin() ); for(int j=mi+1;j<=mx;j++) ans = ans*div%mod; } }}signed main(){
cin >> n >> q; for(int i=2;i
10000 ) continue; for(int j=i+i;j
> x, add(i,x); for(int i=1;i<=q;i++) {
int l,x; cin >> l >> x; add(l,x); cout << ans << "\n"; }}

转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/114483842 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:1493 D. GCD of an Array(动态开点线段树)
下一篇:1493 C. K-beautiful Strings(从后往前贪心[官方题解])

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月11日 04时05分53秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章