题意:给你一个序列a[i],对于每个询问xi,求出有多少个(l,r)对使得gcd(al,al+1...ar)=xi.

表面上是询问,其实只要处理出每个可能的gcd有多少个就好了,当左端点固定的时候,随着右端点的移动,gcd必然是单调非增的,而且个数不会超过log(a[i])个,所以总的不同的个数的上界是nlog(ai),所以求出所有是可行的。

一个分治的做法是这样的,对于一个区间[l,r],分治成[l,mid],[mid+1,r]求解,然后就是合并,合并的时候首先求以[l,mid]右端点为结束点的gcd,然后是[mid+1,r]的左端点为起始点的gcd,两边for一遍,由于不同的gcd最多只有log(ai)个,所以合并的时候就是log(ai)^2。

所以复杂度大致是这样的 T(n)=2*T(n/2)+log(ai)^2+O(n)  所以大致可以看成是T(n)=2*T(n/2)+O(n),所以复杂度大致就是nlogn的级别的。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std; #define maxn 110000
#define ll long long
#define MP make_pair int n;
int a[maxn];
map<int,ll> m; int gcd(int a,int b){
return a&&b? gcd(b,a%b):a+b;
} void solve(int l,int r)
{
if(r-l<=3){
for(int i=l;i<=r;++i){
int g=a[i];
for(int j=i;j<=r;++j){
g=gcd(g,a[j]);
m[g]++;
}
}
return; }
int mid=(l+r)>>1;
solve(l,mid);
solve(mid+1,r);
vector<pair<int,ll> > ls;
vector<pair<int,ll> > rs; int cur=-1;
ll cnt=0;
int g=a[mid];
for(int i=mid;i>=l;--i){
g=gcd(g,a[i]);
if(g!=cur) {
if(cur!=-1) ls.push_back(MP(cur,cnt));
cur=g;cnt=1;
}
else{
++cnt;
}
}
ls.push_back(MP(cur,cnt)); cur=-1;cnt=0;g=a[mid+1];
for(int i=mid+1;i<=r;++i){
g=gcd(g,a[i]);
if(g!=cur) {
if(cur!=-1) rs.push_back(MP(cur,cnt));
cur=g;cnt=1;
}
else{
++cnt;
}
}
rs.push_back(MP(cur,cnt)); for(int i=0;i<ls.size();++i){
for(int j=0;j<rs.size();++j){
int g=gcd(ls[i].first,rs[j].first);
ll num=ls[i].second*rs[j].second;
m[g]+=num;
}
}
} int main()
{
while(~scanf("%d",&n)){
for(int i=1;i<=n;++i){
scanf("%d",a+i);
}
m.clear();
solve(1,n);
int q,xi;
scanf("%d",&q);
while(q--){
scanf("%d",&xi);
if(m.count(xi)) printf("%I64d\n",m[xi]);
else puts("0");
}
}
return 0;
}

Codeforces 475D CGCDSSQ(分治)的更多相关文章

  1. codeforces 475D. CGCDSSQ

    D. CGCDSSQ time limit per test 2 seconds memory limit per test 256 megabytes Given a sequence of int ...

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

    题目链接:点击打开链接 #include <cstdio> #include <cstring> #include <algorithm> #include < ...

  3. Codeforces 475D CGCDSSQ 区间gcd值

    题目链接 题意 给定一个长度为 \(n\) 的数列 \(a_1,...,a_n\) 与 \(q\) 个询问 \(x_1,...,x_q\),对于每个 \(x_i\) 回答有多少对 \((l,r)\) ...

  4. Codeforces 293E 点分治+cdq

    Codeforces 293E 传送门:https://codeforces.com/contest/293/problem/E 题意: 给你一颗边权一开始为0的树,然后给你n-1次操作,每次给边加上 ...

  5. codeforces 161D 点分治

    传送门:https://codeforces.com/problemset/problem/161/D 题意: 求树上点对距离恰好为k的点对个数 题解: 与poj1741相似 把点分治的模板改一下即可 ...

  6. [CF 475D] CGCDSSQ (RMQ)

    题目链接:http://codeforces.com/contest/475/problem/D 是昨天晚上的CF题目,题意是给定你n个数,问你所有子区间内的最小公约数是x的个数是多少 问的康神,了解 ...

  7. Codeforces 888G(分治+trie)

    按位贪心,以当前考虑位是0还是1将数分成两部分,则MST中这两部分之间只会存在一条边,因为一旦有两条或以上的边,考虑两条边在原图中所成的环,显然这两条边有一条是环上的权值最大边,不会出现在MST中.则 ...

  8. Codeforces 888G Xor-MST - 分治 - 贪心 - Trie

    题目传送门 这是一条通往vjudge的高速公路 这是一条通往Codeforces的高速公路 题目大意 给定一个$n$阶完全图,每个点有一个权值$a_{i}$,边$(i, j)$的权值是$(a_{i}\ ...

  9. Codeforces 990G 点分治+暴力

    题意:给出一棵点带权的树,求i\(\in\)[1,200000]所有路径的上点权的gcd==i的个数. 考虑点分治,对于一棵以u为根的子树,如何统计经过u的路径的答案? 显然既然是经过点u的路径,那么 ...

随机推荐

  1. 自己写算法---java的堆的非递归遍历

    import java.io.*; import java.util.*; public class Main { public static void main(String args[]) { S ...

  2. angularjs+nodejs+mongodb三件套

    说实话,自己对于web前段的认识并不是太深入,但是因为项目的需要,所以有的时候肯定会需要接触到web前段的知识点.说到web前端想必大家肯定会想到css+js+html,的确web前端的工作,从某总角 ...

  3. 用Java实现3DES

    3DES,即三重DES,是DES的加强版,也是DES的一个更安全的变形.它使用3个56位(共168位)的密钥对数据进行三次加密,和DES相比,安全性得到了较大的提高. 实际上,3DES是一个过渡的加密 ...

  4. JavaScript 中怎样判断文本框只能输出英文字母、汉字和数字,不能输入特殊字符!

    JS-只能输入中文和英文2008-11-08 10:17在js中用正则表达式对象(RegExp)判断中文 ^[\u0391-\uFFE5]+$英文 ^[A-Za-z]+$中文和英文/^[\u0391- ...

  5. 【转】Git常用命令备忘

    Git配置 git config --global user.name "robbin" git config --global user.email "fankai@g ...

  6. linq里的select和selectmany操作

    Select() 和 SelectMany() 的工作都是依据源值生成一个或多个结果值.Select() 为每个源值生成一个结果值.因此,总体结果是一个与源集合具有相同元素数目的集合.与之相反,Sel ...

  7. P3401: [Usaco2009 Mar]Look Up 仰望

    这道题第一眼还以为是树状数组,于是乎打着打着也是能过的 ; var n,i,j,maxx:longint; h,l:array[..] of longint; p:array[..] of longi ...

  8. PBOC2.0与PBOC3.0的区别

    2013年2月,中国人民银行发布了<中国金融集成电路(IC)卡规范(V3.0)>(以下简称PBOC3.0),PBOC3.0是在中国人民银行2005年颁布的<中国金融集成电路(IC)卡 ...

  9. TFS更新

    我们小组决定将对学长的代码提出改进意见贯穿整个任务的整个过程,随时更新任务进度. 共计预计项目时间为58小时. 每个人都能够达到5到10小时的工作量.

  10. 随堂作业——到底有几个“1”(C++)

    一.设计思路 在课堂上讨论的时候,老师提出的思路是利用之前的结果计算出比它更大的数字的“1”.但是我不是这么想的,我是把输入的正整数每位上的数都分解出来计算.如abc,就先算c,再加上b,最后再加上a ...