Codeforces 475D CGCDSSQ 求序列中连续数字的GCD=K的对数

来源:互联网 发布:淘宝店设置低于7折 编辑:程序博客网 时间:2024/05/01 16:32

题目链接:点击打开链接


#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;}


0 0