【BZOJ】5028: 小Z的加油店
2024-09-07 12:44:01
【算法】数学+线段树/树状数组
【题解】
首先三个操作可以理解为更相减损术或者辗转相除法(待证明),所以就是求区间gcd。
这题的问题在线段树维护gcd只能支持修改成一个数,不支持加一个数。
套路:gcd(a,b,c,d,e)=gcd(a-b,b-c,c-d,d-e,e),也就是所有数的gcd可以转化为所有差值和最后一个数的gcd。
那么只需要查询区间差值gcd和一个数。
对于区间差值gcd查询,区间加数只会导致两个单位的差值变化,所以可以用线段树单点修改区间查询gcd。
对于一个数查询,就用树状数组维护区间加值和单点查询就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=;
struct tree{int l,r,g;}t[maxn*];
int a[maxn],c[maxn],n,m; int read()
{
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
void modify(int x,int k){for(int i=x;i<=n;i+=lowbit(i))c[i]+=k;}
int query(int x){int as=;for(int i=x;i>=;i-=lowbit(i))as+=c[i];return as;}//as给初值
void build(int k,int l,int r){
t[k].l=l;t[k].r=r;
if(l==r)t[k].g=a[l]-a[l+];
else{
int mid=(l+r)>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
t[k].g=gcd(t[k<<].g,t[k<<|].g);
}
}
void add(int k,int x,int v){
if(t[k].l==t[k].r)t[k].g+=v;
else{
int mid=(t[k].l+t[k].r)>>;
if(x<=mid)add(k<<,x,v);
else add(k<<|,x,v);
t[k].g=gcd(t[k<<].g,t[k<<|].g);
}
}
int ask(int k,int l,int r){
if(l<=t[k].l&&t[k].r<=r)return t[k].g;
else{
int mid=(t[k].l+t[k].r)>>,x1=,x2=;
if(l<=mid)x1=ask(k<<,l,r);
if(r>mid)x2=ask(k<<|,l,r);
if(x1&&x2)return gcd(x1,x2);
if(x1)return x1;
return x2;
}
}
int ab(int x){return x>?x:-x;}
int main(){
n=read();m=read();
a[]=;
for(int i=;i<=n;i++)a[i]=read(),modify(i,a[i]-a[i-]);
a[n+]=;
build(,,n);
for(int i=;i<=m;i++){
int p=read(),l=read(),r=read();
if(l>r)swap(l,r);
if(p==){
if(l==r)printf("%d\n",query(r));
else printf("%d\n",ab(gcd(ask(,l,r-),query(r))));//gcd不怕0
}
else{
int v=read();
if(l>)add(,l-,-v);//注意边界!
add(,r,v);
modify(l,v);
if(r<n)modify(r+,-v);
}
}
return ;
}
最新文章
- MySQL SQL Mode及相关问题
- Visual Studio: How to change ipch path in Visual Studio 2010 (.sdf, *.opensdf, ...)
- php代码优化,mysql语句优化,面试需要用到的
- 百度定位并获取县区天气-XML+fragment+sqlite
- MyBatis中的特殊符号[20160713]
- java笔记--查看和修改线程的优先级
- 每日一笔记之3:QTconnect()
- 【usaco】patrol
- HTTP Post请求过程详解
- android139 360 黑名单 增删改查-数据库操作
- Beej网络socket编程指南
- [Data Structure] 红黑树( Red-Black Tree ) - 笔记
- Java虚拟机—垃圾回收算法(整理版)
- Log4net 配置文件组成
- 字符串拼接引发的BUG
- C++多线程同步技巧(四)--- 信号量
- Notes for &#39;Making elephants fly&#39;
- MergeKLists
- Entity Framework工具POCO Code First Generator的使用
- 简单实现textview文本每隔两秒就改变一次