Codeforces 475D CGCDSSQ calculates the logarithm of the continuous number GCD = K in the sequence, codeforces475d
Question link: Click the open link
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <iostream>#include <cmath>using namespace std;typedef long long ll;template <class T>inline bool rd(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; while(c!='-'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); ret*=sgn; return 1;}template <class T>inline void pt(T x) { if(x>9) pt(x/10); putchar(x%10+'0');}/////////////////////////const int N = 100000 + 2;struct Node { int pos,l,r; ll gval; Node(int pos = 0,int l = 0,int r = 0,ll gval = 0):pos(pos),l(l),r(r),gval(gval){} bool operator < (const Node & a) const { if(gval != a.gval) return gval < a.gval; if(pos != a.pos) return pos < a.pos; return r < a.r; }};int n, a[N], tot;vector<Node> vt[N];Node node[N * 50];ll sum[N * 50];void prepare() { for(int i = 0;i <= n;++i) vt[i].clear(); vt[n].push_back(Node(n,n,n,a[n])); Node ntmp; int cnt, Size; ll x; for(int i = n - 1;i >= 1;--i) { Size = vt[i + 1].size(); cnt = 1; vt[i].push_back(Node(i,i,i,a[i])); for(int j = 0;j < Size;++j) { ntmp = vt[i+1][j]; x = __gcd((ll)a[i],ntmp.gval); if(cnt && vt[i][cnt-1].gval == x) vt[i][cnt - 1].r = ntmp.r; else vt[i].push_back(Node(i,ntmp.l,ntmp.r,x)),cnt++; } } tot = 0; for(int i = 1;i <= n;++i) for(int j = 0;j < (int)vt[i].size();++j) node[++tot] = Node(vt[i][j]); sort(node + 1,node + tot + 1); sum[0] = 0; for(int i = 1;i <= tot;++i) sum[i] = sum[i-1] + node[i].r - node[i].l + 1;}int hehe;void work(int x) { int L, R, l = 0, r = tot + 1, mid; while (r - l > 1) { mid = (l + r) >> 1; if (node[mid].gval > x) r = mid; else l = mid; } -- r; if (r == 0 || node[r].gval != x) { putchar('0'); putchar('\n'); return ; } R = r; l = 0; r = tot + 1; while (r - l > 1) { mid = (l + r) >> 1; if (node[mid].gval >= x) r = mid; else l = mid; } L = r; pt(sum[R] - sum[L - 1]); putchar('\n');}int main() { rd(n); for (int i = 1; i <= n; ++i) rd(a[i]); prepare(); int Q, x; rd(Q); while (Q -- > 0) { rd(x); work(x); } return 0;}