Advertisement
welleyth

Untitled

Mar 27th, 2021
789
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.82 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define int long long
  6. #define mp make_pair
  7. #define pb push_back
  8.  
  9. const int N = (int)1e5 + 1;
  10. const int UNDEFINED = -(int)1e12;
  11. vector<int> a;
  12.  
  13. int t[4*N];
  14.  
  15. void build(int v,int l,int r)
  16. {
  17.     if(l > r)
  18.         return;
  19.     if(l == r)
  20.     {
  21.         t[v] = a[l];
  22.         return;
  23.     }
  24.     int m = (l+r)/2;
  25.     build((v<<1),l,m);
  26.     build((v<<1)|1,m+1,r);
  27.     t[v] = __gcd(t[(v<<1)],t[(v<<1)|1]);
  28.     return;
  29. }
  30.  
  31. void update(int v,int l,int r,int pos,int new_val)
  32. {
  33.     if(l == r)
  34.     {
  35.         t[v] = new_val;
  36.         a[l] = new_val;
  37.         return;
  38.     }
  39.     int m = (l + r) / 2;
  40.     if(pos <= m)
  41.         update((v<<1),l,m,pos,new_val);
  42.     else
  43.         update((v<<1)|1,m+1,r,pos,new_val);
  44.     t[v] = __gcd(t[(v<<1)],t[(v<<1)|1]);
  45.     return;
  46. }
  47.  
  48. int get(int v,int l,int r,int tl,int tr)
  49. {
  50.     if(v == 0)
  51.         exit(0);
  52. //    cerr << v << " " << l << " " << r << " " << tl << " " << tr << "\n";
  53.     if(l == tl && r == tr)
  54.         return t[v];
  55.     if(l > r || tl > tr)
  56.         return UNDEFINED;
  57.     int m = (l + r) / 2;
  58.     int c1 = UNDEFINED;
  59.     int c2 = UNDEFINED;
  60.     if(tl >= l)
  61.         c1 = get((v<<1),l,m,tl,min(tr,m));
  62.     if(tr <= r)
  63.         c2 = get((v<<1)|1,m+1,r,max(m+1,tl),tr);
  64.     return (c1 == UNDEFINED ? c2 : (c2 == UNDEFINED ? c1 : __gcd(c1,c2)));
  65. }
  66.  
  67. int n,q;
  68.  
  69. int pref_sum(int pos,vector<pair<int,int> >& pref)
  70. {
  71.     int cur = 1;
  72.     int ans = 0;
  73.     for(int i = 0; i < pref.size(); i++)
  74.     {
  75.         if(cur + pref[i].second > pos)
  76.         {
  77.             ans += max(0ll,(pos - cur + 1)) * pref[i].first;
  78.             break;
  79.         }
  80.         cur += pref[i].second;
  81.         ans += pref[i].first * pref[i].second;
  82.     }
  83.     return ans;
  84. }
  85.  
  86. int suf_sum(int pos,vector<pair<int,int> >& suf)
  87. {
  88.     int cur = 1;
  89.     int ans = 0;
  90.     for(int i = 0; i < suf.size(); i++)
  91.     {
  92.         if(cur + suf[i].second > pos)
  93.         {
  94.             ans += max(0ll,(pos - cur + 1)) * suf[i].first;
  95.             break;
  96.         }
  97.         cur += suf[i].second;
  98.         ans += suf[i].first * suf[i].second;
  99.     }
  100.     return ans;
  101. }
  102.  
  103. int F(int j,vector<pair<int,int> >& pref, vector<pair<int,int> >& suf)
  104. {
  105. //    cout << "F: ";
  106. //    cout << j << " " << n - j - 1 << " | ";
  107. //    cout << pref_sum(j,pref) << " " << suf_sum(n - j - 1,suf) << "\n";
  108.     return pref_sum(j,pref) + suf_sum(n - j - 1,suf);
  109. }
  110.  
  111. int go(int v,int l,int r,int tl,int tr,int val,int cur)
  112. {
  113.     if(tl > tr)
  114.         return 1;
  115.     if(l == r)
  116.     {
  117.         cur = __gcd(cur,a[l]);
  118.         if(val == cur)
  119.             return r;
  120.         return -1;
  121.     }
  122.     int m = (l + r) / 2;
  123.     if(tl == l && tr == r)
  124.     {
  125.         if(__gcd(cur,a[l]) != val)
  126.             return -1;
  127.         int rght = __gcd(cur,t[v<<1]);
  128.         if(val != rght)
  129.             return go(v<<1,l,m,tl,min(m,tr),val,cur);
  130.         rght = __gcd(rght,a[m+1]);
  131.         if(val != rght)
  132.             return m;
  133.         return go(v<<1|1,m+1,r,max(tl,m+1),r,val,__gcd(cur,t[v<<1]));
  134.     }
  135.     int R = go(v<<1|1,m + 1,r,max(m+1,tl),tr,val,__gcd(cur,t[v<<1]));
  136.     if(R != -1)
  137.         return R;
  138.     return go(v<<1,l,m,tl,min(m,r),val,cur);
  139. }
  140.  
  141. int solve()
  142. {
  143.     int y;
  144.     int i = 0;
  145.     vector<pair<int,int> > pref;
  146.     vector<pair<int,int> > suf;
  147.     int l,r;
  148.     int m = 0;
  149.     int tmp;
  150.     while(i < n - 1)
  151.     {
  152.         tmp = get(1,0,n-1,0,i);
  153.         r = go(1,0,n-1,0,i,tmp,0);
  154.     }
  155.  
  156.     i = n - 1;
  157.  
  158.     while(i > 0)
  159.     {
  160.         y = get(1,0,n-1,i,n-1);
  161.  
  162.     }
  163.  
  164.     reverse(suf.begin(),suf.end());
  165.     reverse(pref.begin(),pref.end());
  166.  
  167. //    cout << "Pref:\n";
  168. //    for(auto x : pref)
  169. //        cout << x.first << " " << x.second << "\n";
  170. //
  171. //    cout << "Suf:\n";
  172. //    for(auto x : suf)
  173. //        cout << x.first << " " << x.second << "\n";
  174. //
  175. //    cout << "\n";
  176.  
  177.     int mn = -UNDEFINED;
  178.     l = 0, r = n - 1;
  179.  
  180.     int c1,c2;
  181.  
  182.     while(r - l > 1)
  183.     {
  184.         m = (l + r) / 2;
  185.         if(F(m,pref,suf) > F(m+1,pref,suf))
  186.             l = m + 1;
  187.         else
  188.             r = m;
  189. //        cout << l << " " << r << "\n";
  190.     }
  191.  
  192.     mn = F(l,pref,suf);
  193.  
  194.     if(r - l >= 1)
  195.     {
  196.         for(int T = l + 1; T <= r; T++)
  197.             mn = min(mn,F(T,pref,suf));
  198.     }
  199.  
  200. //    cout << mn << "\n";
  201.  
  202.     return mn + t[1];
  203. }
  204.  
  205. signed main()
  206. {
  207.     ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
  208.  
  209. //    freopen("input.txt","r",stdin);
  210. //    freopen("output.txt","w",stdout);
  211.  
  212.     cin >> n >> q;
  213.  
  214.     a.resize(n);
  215.  
  216.     for(int i = 0; i < n; i++)
  217.     {
  218.         cin >> a[i];
  219.     }
  220.  
  221.     build(1,0,n-1);
  222.  
  223. //    cerr << "BUILD\n";
  224.  
  225.     /// QUERIES
  226.  
  227.     cout << solve() << "\n";
  228.  
  229.     int pos,x;
  230.  
  231.     while(q--)
  232.     {
  233.         cin >> pos >> x;
  234.         update(1,0,n-1,pos-1,x);
  235.         cout << solve() << "\n";
  236.     }
  237.  
  238.     return 0;
  239. }
  240.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement