您的位置:首页 > 其它

中国(北方)大学生程序设计训练赛(第一周)-F(线段树)

2017-03-06 18:55 375 查看
题目链接:F

首先知道等差数列的一个性质: abs(ai−aj)=k∗d ,所以一个区间的任意两个相邻项之差的绝对值的gcd 应该是公差 d ,然后通过最大值-最小值也可以确定一个公差,这两个公差相等的话,且区间内无相同元素,则表明是等差数列。特别的,当最大值==最小值也是等差数列。

查询区间内是否有相同元素可以用线段树查询,pre[i] 表示 a[i] 第一次出现的位置,若区间的 max(pre[i])<l ,则无重复元素。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF=1e9+7;
const int maxn=1e5+7;
int ma[maxn<<2],mi[maxn<<2],gd[maxn<<2],pre[maxn<<2],vis[1000007];
void init()
{
memset(ma,0,sizeof(ma));
memset(mi,0,sizeof(mi));
memset(gd,0,sizeof(gd));
memset(pre,0,sizeof(pre));
memset(vis,0,sizeof(vis));
}
int gcd(int a,int b)
{
if(b==0)    return a;
return a%b?gcd(b,a%b):b;
}
int p;
void push_up(int rt)
{
ma[rt]=max(ma[rt<<1],ma[rt<<1|1]);
mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
gd[rt]=gcd(gd[rt<<1],gd[rt<<1|1]);
pre[rt]=max(pre[rt<<1],pre[rt<<1|1]);
}
void build(int rt,int l,int r)
{
if(l==r)
{
scanf("%d",&ma[rt]);
mi[rt]=ma[rt];
pre[rt]=vis[ma[rt]];
if(l!=1)    gd[rt]=abs(ma[rt]-p);
p=ma[rt];
vis[ma[rt]]=l;
return ;
}
if(l==r)    return ;
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
push_up(rt);
}

int query_max(int rt,int l,int r,int ql,int qr)
{
if(l>=ql&&r<=qr) return ma[rt];
int res=-INF;
int mid=(l+r)>>1;
if(ql<=mid) res=max(res,query_max(rt<<1,l,mid,ql,qr));
if(qr>mid)  res=max(res,query_max(rt<<1|1,mid+1,r,ql,qr));
return res;
}
int query_min(int rt,int l,int r,int ql,int qr)
{
if(l>=ql&&r<=qr)    return mi[rt];
int res=INF;
int mid=(l+r)>>1;
if(ql<=mid) res=min(res,query_min(rt<<1,l,mid,ql,qr));
if(qr>mid)  res=min(res,query_min(rt<<1|1,mid+1,r,ql,qr));
return res;
}
int query_pre(int rt,int l,int r,int ql,int qr)
{
if(l>=ql&&r<=qr)    return pre[rt];
int res=-INF;
int mid=(l+r)>>1;
if(ql<=mid) res=max(res,query_pre(rt<<1,l,mid,ql,qr));
if(qr>mid)  res=max(res,query_pre(rt<<1|1,mid+1,r,ql,qr));
return res;
}
int query_gcd(int rt,int l,int r,int ql,int qr)
{
if(l>=ql&&r<=qr)    return gd[rt];
int mid=(l+r)>>1;
if(qr<=mid) return query_gcd(rt<<1,l,mid,ql,qr);
if(ql>mid)  return query_gcd(rt<<1|1,mid+1,r,ql,qr);
return gcd(query_gcd(rt<<1,l,mid,ql,qr),query_gcd(rt<<1|1,mid+1,r,ql,qr));
}
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
init();
int l,r;
build(1,1,n);
while(q--)
{
scanf("%d%d",&l,&r);
int low=query_min(1,1,n,l,r);
int high=query_max(1,1,n,l,r);
if(low==high||l==r) puts("Yes");
else if(query_pre(1,1,n,l,r)<l&&1LL*query_gcd(1,1,n,l+1,r)*(r-l)==1LL*(high-low)) puts("Yes");
else puts("No");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐