题意:给出一个序列,后q次询问,求给定区间gcd及整个序列有多少个序列的gcd和这个值相同

首先线段树维护区间gcd建树,之后预处理出每个gcd有多少个子序列,这时需要dp,

dp[i][tmp]表示以第i个数a[i]结尾的序列中有dp[i][tmp]个连续子序列的gcd值为tmp,dp[i]是一个map

那么,dp[i][tmp]如何求?显然,tmp是由dp[i-1]中所有gcd值与a[i]求gcd得到的,(因为是连续子序列的gcd值,所以由a[i-1]转移而来)。

这里加个滚动数组优化的思想,只需要两个unordered_map即可,最后用一个map的ans记录每个gcd值有多少个序列即可,复杂度应该位于o(nlogn)到o(n(logn)^2)之间

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int maxn=1e5+;
ll gcd[maxn<<];
ll a[maxn];
void build(int l,int r,int rt)
{
if(l==r){
gcd[rt]=a[l];
return;
}
int m=(l+r)>>;
build(l,m,rt<<);
build(m+,r,rt<<|);
gcd[rt]=__gcd(gcd[rt<<],gcd[rt<<|]);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return gcd[rt];
int m=(l+r)>>;
ll res=;
if(L<=m)res=query(L,R,l,m,rt<<);
if(R>m)res=__gcd(res,query(L,R,m+,r,rt<<|));
return res;
}
unordered_map<ll,ll>ans;
unordered_map<ll,ll>dp[];
int main()
{
int t,ca=;
cin>>t;
while (t--)
{
int n;
cin>>n;
for(int i=;i<=n;i++)scanf("%lld",&a[i]);
dp[].clear();
dp[].clear();
build(,n,);
dp[][a[]]=;
ans[a[]]=;
for(int i=;i<=n;i++)
{
ans[a[i]]++;
dp[(i&)^][a[i]]=;
for(auto xy=dp[i&].begin();xy!=dp[i&].end();xy++)
{
ll tmp=__gcd(xy->first,a[i]);
dp[(i&)^][tmp]+=xy->second;
ans[tmp]+=xy->second;
}
dp[i&].clear();
}
int q;
cin>>q;
printf("Case #%d:\n",ca++);
while (q--)
{
int l,r;
scanf("%d%d",&l,&r);
ll res=query(l,r,,n,);
printf("%lld %lld\n",res,ans[res]);
}
}
return ;
}

HDU 5726 线段树+dp的更多相关文章

  1. hdu 4747 线段树/DP

    先是线段树 可以知道mex(i,i),mex(i,i+1)到mex(i,n)是递增的. 首先很容易求得mex(1,1),mex(1,2)......mex(1,n) 因为上述n个数是递增的. 然后使用 ...

  2. HDU 3607 线段树+DP+离散化

    题意:从左往右跳箱子,每个箱子有金币数量,只能从矮处向高处跳,求最大可获得金币数,数据规模1<=n<=1e5. 显然是一个dp的问题,不难得出dp[ i ] = max(dp[j] )+v ...

  3. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  4. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  5. hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  6. hdu 3974 线段树 将树弄到区间上

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  8. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

随机推荐

  1. (转)浅谈C中的malloc和free

    原帖及讨论:http://bbs.bccn.net/thread-82212-1-1.html 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的malloc()和free()两个函数 ...

  2. Linux 线程Demo

    #include <stdio.h> #include <pthread.h> struct char_print_params { char character; int c ...

  3. Ubuntu下qemu环境搭建vexpress开发平台

    在查找资料过程中,发现自己搭建虚拟的arm环境的话,有一个比较好的软件就是qemu了,当然还有其他的,大家各投所好就好. 接下来说一下qemu环境搭建过程. 其实搭建很简单,作为小白,我还是捣鼓了两三 ...

  4. CSS:CSS Display(显示) 与 Visibility(可见性)

    ylbtech-CSS:CSS Display(显示) 与 Visibility(可见性) 1.返回顶部 1. CSS Display(显示) 与 Visibility(可见性) display属性设 ...

  5. WIN7下怎么安装iis教程

    点击开始→控制面板,然后再点击程序,勿点击卸载程序,否则到不了目标系统界面. 2 然后在程序和功能下面,点击打开和关闭windows功能. 3 进入Windows功能窗口,然后看到internet信息 ...

  6. CSS实现背景图片固定

    body { background-image:url('bg.jpg'); background-repeat: no-repeat; background-attachment: fixed; / ...

  7. scala 实现算法

    快速排序 def sort(xs: Array[Int]): Array[Int] = if (xs.length <= 1) xs else { val pivot = xs(xs.lengt ...

  8. 【gcc】更新下载编译gcc遇到的各种问题

    帮学长的oj升级gcc版本.遇到了贼多问题.. [悲惨的开始] 安装gcc版本推荐ustc的mirror的下载,超快der... https://mirrors.ustc.edu.cn/gnu/gcc ...

  9. Vue-cli开发笔记一----------项目的结构

    配置文件package.json: 搜索了配置的原理:https://segmentfault.com/a/1190000000344102 里面讲到:npm会在package.json文件中找scr ...

  10. Redis探索之路(一):Redis简介

    一:NOSQL NotOnlySQL 反SQL运动,非关系型数据库(区别于Mysql关系型书库). 随着Web2.0兴起,“高性能”,“高并发”成为主流. NoSQL以key-value形式存储数据, ...