题意:给你一串数a再给你一些区间(lef,rig),求出a[lef]%a[lef+1]...%a[rig]

题解:我们可以发现数字a对数字b取模时:如果a<b,则等于原数,否则a会变小至少一半。就是说a最多成功取模(log2 a)次,所以我们只需要每次在区间内找到最前面一个小于等于a的值,接着更新a与区间左端点,直到没有值比a小或者区间取模完成。

我们可以使用线段树求出区间内小于某个值的最前一个位置,具体方法就是:父节点记录区间最小值,接着当这一整段的最小值小于等于给定的值时就递归进此子树(另一棵子树还是可能递归,因为可能前一个子树包含的区间大于所求的区间),这样我们知道第一次递归到叶子节点时就一定是最前一个小于等于此值的位置(如果有这个值的话)。

//别人的代码,自己还没写
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=<<;
int nnum[Max],cnt,flag;
int segtr[Max];
struct node
{
int mmin,mpos;
}res;
void Upnow(int now,int next)
{
segtr[now]=min(segtr[next],segtr[next|]);
return;
}
void Create(int sta,int enn,int now)
{
if(sta==enn)
{
scanf("%d",&segtr[now]);
nnum[cnt++]=segtr[now];//记录每个位置的值
return;
}
int mid=dir(sta+enn,);
int next=mul(now,);
Create(sta,mid,next);
Create(mid+,enn,next|);
Upnow(now,next);
return;
}
void Query(int sta,int enn,int now,int x,int y,int z)
{
if(sta>=x&&enn<=y)
{
if(sta==enn)//到叶子节点
{
flag=;//表示只能到一次叶子节点
if(segtr[now]<=z)//找到
{
res.mmin=segtr[now];
res.mpos=sta;
}
return;
}
if(segtr[now]>z)//这一段不需要再递归
return;
}
int mid=dir(sta+enn,);
int next=mul(now,);
if(mid>=x&&!flag&&segtr[next]<=z)//之前没到叶子,子树区间最小值小于等于给定的值
Query(sta,mid,next,x,y,z);
if(mid<y&&!flag&&segtr[next|]<=z)
Query(mid+,enn,next|,x,y,z);
return;
}
int main()
{
int t,n,m;
int lef,rig;
scanf("%d",&t);
while(t--)
{
cnt=;
scanf("%d",&n);
Create(,n,);
scanf("%d",&m);
for(int i=;i<=m;++i)
{
scanf("%d %d",&lef,&rig);
if(lef==rig)//只有一个值
{
printf("%d\n",nnum[lef]);
continue;
}
int ans=nnum[lef];
lef++;
while()
{
res.mmin=Inf,res.mpos=-;
flag=;
Query(,n,,lef,rig,ans);
if(ans>=res.mmin)//成功取模
{
ans=ans%res.mmin;
lef=res.mpos+;
}
else
break;
if(lef>rig||ans==)//结束条件
break;
}
printf("%d\n",ans);
}
}
return ;
}

单调栈写法

/*#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std; int b[100005*4];
long long a[100005];
int c,l,r; void build(int node,int left,int right)
{
if(left==right)
{
scanf("%d",&b[node]);
a[c++]=b[node];
return;
}
build(node*2,left,(left+right)/2);
build(node*2+1,(left+right)/2+1,right);
b[node]=min(b[node*2],b[node*2+1]);
return;
} long long query(int x,int y,int left,int right,int node,int val)
{
if(x==y)
{
if (b[node]<=val) return left;
else return -1;
}
int mid = (left+right)/2;
int ans=-1;
if(x<=mid && b[node*2]<=val)
{
ans=query(x,y,left,mid,node*2,val);
return ans;
}
if(y>mid && b[node*2+1]<=val)
{
ans=query(x,y,mid+1,right,node*2+1,val);
return ans;
}
return -1;
} //以上是自己写的线段树,错误多多 int main()
{
int T,n,m;
long long ans;
while(~scanf("%d",&T))
{
while(T--)
{
scanf("%d",&n);
c=1;
build(1,1,n);
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&l,&r);
ans=a[l];
while(l<r)
{
l=query(l+1,r,1,n,1,a[l]);
if (l==-1) break;
ans=ans%a[l];
}
printf("%lld\n",ans);
}
}
}
return 0;
}
*/ #include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std; int a[],b[]; int main()
{
int T,n,m,l,r;
int ans;
while(~scanf("%d",&T))
{
while(T--)
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=n;i++)
{
b[i]=-;
for(int j=i+;j<=n;j++)
if (a[j]<=a[i]) {b[i]=j;break;}
}
// for(int i=1;i<=n;i++) printf("%d ",b[i]);
// printf("\n");
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&l,&r);
ans=a[l];
while(l<r)
{
if(b[l]==- || b[l]>r) break;
ans=ans%a[b[l]];
l=b[l];
}
printf("%d\n",ans);
}
}
}
return ;
}

HDU 5875 Function (线段树+gcd / 单调栈)的更多相关文章

  1. [CSP-S模拟测试]:陶陶摘苹果(线段树维护单调栈)

    题目传送门(内部题116) 输入格式 第一行两个整数$n,m$,如题 第二行有$n$个整数表示$h_1-h_n(1\leqslant h_i\leqslant 10^9)$ 接下来有$m$行,每行两个 ...

  2. Wannafly挑战赛18 E 极差(线段树、单调栈)

    Wannafly挑战赛18 E 极差 题意 给出三个长度为n的正整数序列,一个区间[L,R]的价值定义为:三个序列中,这个区间的极差(最大值与最小值之差)的乘积. 求所有区间的价值之和.答案对\(2^ ...

  3. [JXOI2017]颜色 线段树扫描线 + 单调栈

    ---题面--- 题解: 首先题目要求删除一些颜色,换个说法就是要求保留一些颜色,那么观察到,如果我们设ll[i]和rr[i]分别表示颜色i出现的最左边的那个点和最右边的那个点,那么题目就是在要求我们 ...

  4. Educational Codeforces Round 61 (Rated for Div. 2) G(线段树,单调栈)

    #include<bits/stdc++.h>using namespace std;int st[1000007];int top;int s[1000007],t[1000007];i ...

  5. [BZOJ 2957]楼房重建(THU2013集训)(线段树维护单调栈)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2957 分析: 根据题意,就是比较斜率大小 只看一段区间的话,那么这段区间能看见的楼房数量就是这 ...

  6. ACM学习历程—HDU 5289 Assignment(线段树 || RMQ || 单调队列)

    Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro ...

  7. 洛谷 P4198 楼房重建 线段树维护单调栈

    P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...

  8. [CSP-S模拟测试]:God Knows(线段树维护单调栈)

    题目描述 小$w$来到天堂的门口,对着天堂的大门发呆.大门上有一个二分图,左边第$i$个点连到右边第$p_i$个点.(保证$p_i$是一个排列).小$w$每次可以找左边某个对应连线尚未被移除的点$i$ ...

  9. 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP

    1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...

随机推荐

  1. Hbase环境安装

    说明: (Hbase依赖于HDFS和zookeeper) 参考我的博客: https://www.cnblogs.com/654wangzai321/p/8603498.html https://ww ...

  2. “使用驱动器中J:的光盘之前需要将其格式化

    不知道神马原因致使U盘无法打开——大家千万注意:以后遇见这种情况千万别格式化(当然如果你的U盘或者硬盘里没有重要东西那就另当别论),进入“开始-cmd”,因为我的U盘在电脑上读出来是J盘,所以在cmd ...

  3. oracle中job定时器任务

    对于DBA来说,经常要数据库定时的自动执行一些脚本,或做数据库备份,或做数据的提炼,或做数据库的性能优化,包括重建索引等等的工作.但是,Oracle定时器Job时间的处理上,千变万化,今天我把比较常用 ...

  4. thinkerCMS是一款thinkphp写的微型cms框架可以参考下

    http://www.thinkphp.cn/code/1764.html                       thinkphp官网thinkercms介绍 http://cms.thinke ...

  5. jQuery height() 需要注意的地方

    var aNode = $('#id'); var height = aNode.height(); //如果在获取height前,aNode已经是display:none 或者说 aNode是隐藏的 ...

  6. linux 安装vscode

    滚动安装vscode 需要先添加源,然后install 以centos为例: sudo rpm --import https://packages.microsoft.com/keys/microso ...

  7. kali安装机场v2ray客户端

    为了方便查找资料,之前安装的ssr在kali上面,感觉速度不怎么快,相比windows和android上慢很多,所以打算在kali上面装个机场试试,看官方介绍说机场比ssr速度更快,下面是安装步骤: ...

  8. 20145322《Java程序设计》第3次实验报告

    实验内容,, 组队使用 git 上传代码并且互相下载对方代码修改之后再上传. 实现代码的重载 一. 使用git 上传代码 过程如图: 仨人成功上传后的代码图如下: 使用git 相互更改代码 执行git ...

  9. linux 块设备-整理(一)

    1. 基本概念: linux设备驱动开发详解(宋宝华): 字符设备与块设备 I/O 操作的不同如下. (1)块设备只能以块为单位接受输入和返回输出,而字符设备则以字节为单位. 大多数设备是字符设备,因 ...

  10. IDEA 安装mybatis 插件 可以通过mapper定位到xml

    在使用IDEA的时候 ,通过mapper类定位到 xml文件是让人很头疼的问题! 无意中发现了这个插件!可以通过类方法直接定位到xml中!比较强大!哈哈! 这玩意好像是付费的! 不过不破解也能用! 哈 ...