很简单的一个题的,结果后台数据有误,自己又太傻卡了3个小时。。。

题意:给你一串数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 ;
}

最新文章

  1. 视图views粗略理解
  2. asp.net 查询好的数据后 排序显示在桌面上
  3. [JSP]用户注册
  4. autorelease的对象何时被释放
  5. Javascript 笔记与总结(2-14)事件
  6. css 去除input 获取焦点的蓝色边框
  7. CENTOS6上禁用IPV6和DHCP
  8. Apache 支持.htaccess
  9. Acess错误:&quot;文件共享锁定数溢出&quot;
  10. magento获取一些值的方法函数
  11. 【iOS】7.4 定位服务-&gt;3.4 地图框架MapKit 功能4:地图截图
  12. Centos7.2 启用iptables
  13. LINUX PID 1和SYSTEMD 专题
  14. 目录命令(RD)
  15. Restful levels and Hateoas
  16. 【XSY2750】Mythological V 2-sat
  17. 两个栈实现队列 Python实现
  18. drupal7,注册成功之后想跳转到指定页面,该怎么破?
  19. angular 如何使用第三方组件ng-bootstrap
  20. Codeforces Gym 100513F F. Ilya Muromets 水题

热门文章

  1. MySQL thread pool【转】
  2. 内存管理_JAVA内存管理
  3. ABAP 将SAP用户ID转换成用户名
  4. 修改UINavigationController返回按钮颜色
  5. pthread_cond_wait的原子性
  6. Greedy:Cow Acrobats(POJ 3045)
  7. 【leetcode】Integer to Roman &amp; Roman to Integer(easy)
  8. php面向对象加载类、常用设计模式
  9. 方法重载的小demo
  10. Java动态代理一Proxy