求助RE,线段树求区间最大公约数
  • 板块灌水区
  • 楼主azaa414
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/8/5 20:51
  • 上次更新2024/8/5 21:42:39
查看原帖
求助RE,线段树求区间最大公约数
643605
azaa414楼主2024/8/5 20:51

显示Runtime Error Segmentation fault

题目描述

给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:

C l r d,表示把 A[l],A[l+1],…,A[r] 都加上 d。

Q l r,表示询问 A[l],A[l+1],…,A[r] 的最大公约数(GCD)。

对于每个询问,输出一个整数表示答案。

输入格式

第一行两个整数 N,M。

第二行 N 个整数 A[i]。

接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。

输出格式

对于每个询问,输出一个整数表示答案。

每个答案占一行。

输入输出样例

输入数据

1
5 5
1 3 5 7 9
Q 1 5
C 1 5 1
Q 1 5
C 3 3 6
Q 2 4

输出数据 1

1
2
4

数据范围

N≤500000,M≤100000,1≤A[i]≤1018∣d∣≤1018N≤500000,M≤100000,1≤A[i]≤10^{18}∣d∣≤10^{18} 保证数据在计算过程中不会超过 long long 范围。

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define ll long long
#define INF 8000040
using namespace std;
ll n,m;
ll a[INF],b[INF],c[INF];
struct node{
  ll l,r;
  ll dat;
}tre[INF];
inline ll read();
inline void write(ll x);
ll lb(ll x)
{
  return x&(-x);
}
void add(ll x,ll y,ll (&temp)[INF])
{
  for(;x<=n;x+=lb(x))
  	temp[x]+=y;
}
ll ask(ll x,ll (&temp)[INF])
{
  ll s=0;
  for(;x;x-=lb(x)) s+=temp[x];
  return s;
}
ll gcd(ll a,ll b)
{
  if(a<0) a=-a;
  if(b<0) b=-b;
  if(a<b) a^=b,b^=a,a^=b;
  if(!b)return a;
  if((!(a&1))&&(!(b&1))) return gcd(a>>1,b>>1)<<1;
  else if((a&1)&&(!(b&1)))return gcd(a,b>>1);
  else if((!(a&1))&&(b&1))return gcd(a>>1,b);
  else return gcd(a-b,b);
} 
void build(ll l,ll r,ll p)
{
  tre[p].l=l;tre[p].r=r;
  if(l==r)
  {
  	tre[p].l=tre[p].r=l;
  	tre[p].dat=b[l];
  	return;
  }
  ll mid=(l+r)>>1;
  build(l,mid,p*2);
  build(mid+1,r,p*2+1);
  tre[p].dat=gcd(tre[p*2].dat,tre[p*2+1].dat);
}
void change(ll x,ll y,ll p)
{
//	cout<<endl<<"p:"<<p<<endl;
  if(tre[p].l==tre[p].r)
  {
  	tre[p].dat+=y;
  	return;
  }
  ll mid=(tre[p].l+tre[p].r)>>1;
  if(x<=mid) change(x,y,p*2);
  else change(x,y,p*2+1);
  tre[p].dat=gcd(tre[p*2].dat,tre[p*2+1].dat);
  
}
ll asktre(ll l,ll r,ll p)
{
//	cout<<endl<<"p:"<<p<<endl;
  if(tre[p].l>=l&&tre[p].r<=r) return tre[p].dat;
  ll mid=(tre[p].l+tre[p].r)>>1,s;
  bool f=0;
  if(l<=mid) s=asktre(l,r,p*2),f=1;
  if(r>mid) s=f?gcd(s,asktre(l,r,p*2+1)):asktre(l,r,p*2+1);
  return s;
}
int main()
{
  n=read();m=read();
  for(int i=1;i<=n;++i)
  	a[i]=read(),b[i]=a[i]-a[i-1];
  build(1,n,1);
  while(m--)
  {
  	char ch=getchar();
  	if(ch=='C')
  	{
  		ll l=read(),r=read(),d=read();
  		change(l,d,1);
  		if(r+1<=n)	change(r+1,-d,1);
  		add(l,d,c);
  		add(r+1,-d,c);
  	}
  	if(ch=='Q')
  	{
  		ll l=read(),r=read();
  		write(gcd(a[l]+ask(l,c),asktre(l+1,r,1)));
  		putchar('\n');
  	}
  }
  return 0;
}
inline ll read()
{
  ll x=0,f=1;
  char ch=getchar();
  while (ch<'0'||ch>'9')
  {
  	if (ch=='-')
  		f=-1;
  	ch=getchar();
  }
  while(ch>='0'&&ch<='9')
  {
  	x=(x<<1)+(x<<3)+(ch^48);
  	ch=getchar();
  }
  return x*f;
}
inline void write(ll x)
{
  if(x<0) putchar('-'),x=-x;
  if(x>9)
  	write(x/10);
  putchar(x%10+'0');
  return;
}
2024/8/5 20:51
加载中...