题意:给你一串数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. Windows资源监控神器——perfmon

    一.简述 笔者在用lr中control监控Windows资源的时候,有时候总是遇到卡死和报错,所以就发现了Windows自带的监控神器————perfmon. Perfmon提供了图表化的系统性能实时 ...

  2. 【Unity3D】使用MD5值,确保本地Sqlite数据库内容没有被篡改

    Sqlite的应用场景 在判断是否使用存储格式为Sqlite模式的标准,我们的标准是内容只读.也就是说,除非发布者修改Sqlite内容,玩家只有读取的权限. 换个角度说,Sqlite里面的数据都是游戏 ...

  3. 网络虚拟化 SDN

    一.Linux Bridge :Linux中的网桥 假设宿主机有 1 块与外网连接的物理网卡 eth0,上面跑了 1 个虚机 VM1,现在有个问题是: 如何让 VM1 能够访问外网? 至少有两种方案 ...

  4. ORA-00257: archiver error的解决方法

    背景:多个用户同时做测试数据,有时候突然Oracle系统就崩溃了,然后报一个ORA-00257: archiver error. Connect internal only, until freed的 ...

  5. Android-服务中监听电源键和Home键的广播、在锁屏下仍然工作的方法

    Android-服务中监听电源键和Home键的广播  http://blog.csdn.net/u014657752/article/details/49512485 Android开发之如何监听让服 ...

  6. 【c++ primer, 5e】函数指针

    简单的示例: #include <iostream> using namespace std; int sum(int x, int y) { return x + y; } int ma ...

  7. Web安全学习笔记之Kali配置国内软件更新源

    0x0 前言 Kali安装完成后,默认是国外官方的更新源,更新速度4kb/s太酸爽了... 0x1 把更新源设置为国内阿里云或者中科大的镜像源 命令行:leafpad /etc/apt/sources ...

  8. Docker 的一些使用心得

    Docker 的使用心得 预备知识·必备· bash(bsd) Net ,ip know hot to search in Google and Baidu 安装 一般找一个不错的网络环境...不然玩 ...

  9. CNN笔记:通俗理解卷积神经网络【转】

    本文转载自:https://blog.csdn.net/v_july_v/article/details/51812459 通俗理解卷积神经网络(cs231n与5月dl班课程笔记) 1 前言 2012 ...

  10. 爬虫框架Scrapy之详解

    Scrapy 框架 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页 ...