D. GCD of an Array

题目链接:https://codeforces.com/contest/1493/problem/D

题意:q次询问,每次让一个数乘上x ,每次询问整个区间的gcd  取模1e9+7

思路:要取模 所以肯定是往质因数的方向考虑, 存下每个数质因数的出现次数 用map存

然后每次的答案ans可以通过上一次的来更新, 每次新加进来的x 质因数分解

用multipleset 来维护一个集合内的质因数的指数, 多集的集合即为出现的次数 当集合数量等于n的时候

就可以取 其中的最小值来更新贡献答案 

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=2e5+10;
  4 const int mod=1e9+7;
  5 #define ll long long
  6 #define ull unsigned long long
  7 #define pi pair<int,ll>
  8 #define fi first
  9 #define sc second
 10 #define pb push_back
 11 int a[maxn];
 12 map<int,int>mp[maxn];
 13 multiset<int>s[maxn];
 14 int f[maxn];
 15 int vis[maxn];
 16 
 17 
 18 
 19 int main()
 20 {
 21     ios::sync_with_stdio(0);
 22     cin.tie(0);
 23     int n,q;
 24     cin>>n>>q;
 25     for(int i=1;i<=n;i++) cin>>a[i];
 26     vector<int>p;
 27     for(int i=2;i<maxn;i++)
 28     {
 29         if(f[i]) continue;
 30         p.pb(i);
 31         for(int j=i;j<maxn;j+=i)
 32         {
 33             f[j]=1;
 34         }
 35     }
 36 
 37     for(int i=1;i<=n;i++)
 38     {
 39         int x=a[i];
 40         for(auto &v:p)
 41         {
 42             if(v*v>x) break;
 43             int cnt=0;
 44             while(x%v==0) x/=v,cnt++;
 45             if(cnt)
 46             {
 47                 mp[i][v]=cnt;
 48                 s[v].insert(mp[i][v]);
 49             }
 50         }
 51         if(x)
 52         {
 53             int sum=mp[i][x];
 54             mp[i][x]=1;
 55             s[x].insert(1);
 56         }
 57     }
 58     ll ans=1;
 59 
 60     for(auto &v:p)
 61     {
 62         if(s[v].size()==n)
 63         {
 64             int y=*s[v].begin();
 65             vis[v]=y;
 66             for(int i=0;i<y;i++)
 67             {
 68                 ans*=v;
 69                 ans%=mod;
 70             }
 71         }
 72     }
 73 
 74 
 75 
 76 
 77     while(q--)
 78     {
 79         int i,x;
 80         cin>>i>>x;
 81         vector<int>num;
 82         for(auto &v:p)
 83         {
 84             if(v*v>x) break;
 85             int cnt=0;
 86             while(x%v==0) x/=v,cnt++;
 87             if(cnt)
 88             {
 89                 num.pb(v);
 90                 int sum=mp[i][v];
 91                 if(sum)
 92                     s[v].erase(s[v].find(sum));
 93                 mp[i][v]+=cnt;
 94                 s[v].insert(mp[i][v]);
 95             }
 96         }
 97         if(x)
 98         {
 99             num.pb(x);
100             int sum=mp[i][x];
101             if(sum)
102                 s[x].erase(s[x].find(sum));
103             mp[i][x]++;
104             s[x].insert(mp[i][x]);
105         }
106         for(auto &v:num)
107         {
108             if(s[v].size()!=n) continue;
109             int y=*s[v].begin();
110             if(y>vis[v])
111             {
112                 int ci=y-vis[v];
113                 vis[v]=y;
114                 for(int j=0;j<ci;j++)
115                 {
116                     ans*=v;
117                     ans%=mod;
118                 }
119             }
120         }
121         cout<<ans<<'\n';
122     }
123 
124 }
View Code

 

posted @ 2021-03-07 16:03  canwinfor  阅读(202)  评论(0)    收藏  举报