Codeforces 474F(分块)

来源:互联网 发布:抓阄软件 编辑:程序博客网 时间:2024/06/10 13:01

题意:给长度为N的数列,t个询问[l,r],求区间[l,r]中不能整除区间中其它数的数有多少个。

这题和之前一道分块题简直一模一样,于是就用分块做了。

没个询问的答案,就是区间长度减去值为区间gcd的数的个数。那么预处理出每段的答案及这段的gcd,可以很容易推出答案。

#include<bits/stdc++.h>using namespace std;const int N = 5e5 + 20;const int M = 500;int n, t, s[N], l, r;int unit, siz, ans[M][M], gans[M][M];int g, temp, cnt;int gcd(int a, int b){    return b ? gcd(b, a % b) : a;}int main(){    memset(ans, 0, sizeof(ans));    memset(gans, 0, sizeof(gans));    scanf("%d", &n);    for(int i = 1; i <= n; i++)        scanf("%d", &s[i]);    unit = sqrt(n);    siz = (n + unit) / unit;    for(int i = 0; i <= n; i += unit){        g = s[i + 1], cnt = 0, temp;        for(int j = i; j <= n; j++){            temp = gcd(g, s[j]);            if(g != temp) cnt = 0, g = temp;            if(s[j] == g) cnt++;            if(j % unit == 0) ans[i / unit][j / unit] = cnt, gans[i / unit][j / unit] = g;        }        ans[i / unit][siz] = cnt;        gans[i / unit][siz] = g;     }    scanf("%d", &t);    while(t--){        scanf("%d%d", &l, &r);        int x = (l + unit) / unit * unit, y = r / unit * unit;        int res;        if(x >= y) g = s[l], res = 1, x = y = l;        else g = gans[x / unit][y / unit], res = ans[x / unit][y / unit];        for(int i = l; i < x; i++){            temp = gcd(g, s[i]);            if(g != temp) res = 0, g = temp;            if(g == s[i]) res++;        }        for(int i = y + 1; i <= r; i++){            temp = gcd(g, s[i]);            if(g != temp) res = 0, g = temp;            if(g == s[i]) res++;        }        printf("%d\n", r - l + 1 - res);    }    return 0;}
原创粉丝点击