HDU 5726 线段树+dp
题意:给出一个序列,后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的更多相关文章
- hdu 4747 线段树/DP
先是线段树 可以知道mex(i,i),mex(i,i+1)到mex(i,n)是递增的. 首先很容易求得mex(1,1),mex(1,2)......mex(1,n) 因为上述n个数是递增的. 然后使用 ...
- HDU 3607 线段树+DP+离散化
题意:从左往右跳箱子,每个箱子有金币数量,只能从矮处向高处跳,求最大可获得金币数,数据规模1<=n<=1e5. 显然是一个dp的问题,不难得出dp[ i ] = max(dp[j] )+v ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)
[题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...
- 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 ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
随机推荐
- STM32嵌入式开发学习笔记(三):使用按键控制小灯
按键和小灯一样,也是通过GPIO外设与主板连接,也是通过GPIO_InitStruct类型结构体控制其工作. 查阅技术手册,按钮连接GPIOA控制下的管脚0. 但与之不同的是,按键是一种输入设备,输入 ...
- thinkphp 表单令牌
表单令牌 ThinkPHP支持表单令牌验证功能,可以有效防止表单的重复提交等安全防护.要启用表单令牌功能,需要配置行为绑定, 在应用或者模块的配置目录下面的行为定义文件tags.php中 就是在你的 ...
- vue中配置可修改的服务器接口api
https://www.jianshu.com/p/377bfd2d9034?utm_campaign 太坑了,找了全网,几乎都不能用,也不知道哪写错了,这个是可以用的.
- Linux 下tomcat+jdk+mysql安装
JDK 1.用xftp把 jdk1.8.0_65上传到local下 给他赋予最高权限 1)切换到顶级目录 cd ~ 2)然后切换到上级目录 cd .. 3)切换到local路径下 cd /us ...
- Apache Solr远程命令执行复现
环境 /vulhub/solr/CVE-2019-0193/ 创建一个集合 docker-compose exec solr bash bin/solr create_core -c test -d ...
- .net 委托 +lamda表达式
1.委托与类同级 想当于定义了一个类型 如 delegate int Sum(int a, int b);// 在声明类之前声明 2.这里可以在类里写个函数 public int sumAB(int ...
- 净心诀---python3生成器进阶
列表推导式 把需要用一个函数写成的小功能,利用一行表达式完成 例子: l = [1,2,3,4,5] # 所有的偶数都放到新的列表中 # 正常函数 def Lst(): li = [] for i i ...
- 页面上有3个输入框:分别为max,min,num;三个按钮:分别为生成,排序,去重;在输入框输入三个数字后,先点击生成按钮,生成一个数组长度为num,值为max到min之间的随机整数点击排序,对当前数组进行排序,点击去重,对当前数组进行去重。 每次点击之后使结果显示在控制台
<!DOCTYPE html> <html> <head> <!-- 页面上有3个输入框:分别为max,min,num:三个按钮:分别为生成,排序,去重: 在 ...
- 2019-9-25-如何让-USB-设备不显示安全删除硬件弹出选项
title author date CreateTime categories 如何让 USB 设备不显示安全删除硬件弹出选项 lindexi 2019-09-25 11:58:19 +0800 20 ...
- xinetd - 扩展的互联网服务守护进程
总览 SYNOPSIS xinetd [options] 描述 DESCRIPTION xinetd 执行与 inetd 相同的任务:它启动提供互联网服务的程序.与在系统初始化时启动这些服务器,让它们 ...