社区讨论
线段树求问
P1890gcd 区间参与者 7已保存回复 21
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 21 条
- 当前快照
- 1 份
- 快照标识符
- @mi6z90bu
- 此快照首次捕获于
- 2025/11/20 13:14 4 个月前
- 此快照最后确认于
- 2025/11/20 16:35 4 个月前
代码
CPP// luogu-judger-enable-o2
#include<iostream>
#include<algorithm>
#define LS rt<<1,l,mid
#define RS rt<<1|1,mid+1,r
#define PushUp tree[rt].gcd=gcd(tree[rt<<1].gcd,tree[rt<<1|1].gcd)
using namespace std;
const int N=5000000;
int a[N];
int gcd(int a,int b)
{return !b?a:gcd(b,a%b);}
struct Tr{int l,r,gcd;}tree[N];
void build(int rt,int l,int r)
{
tree[rt].l=l,tree[rt].r=r;
if(l==r)
{
tree[rt].gcd=a[l];
return;
}
int mid=(l+r)>>1;
build(LS);build(RS);
PushUp;
}
int find(int rt,int l,int r)
{
if(l<=tree[rt].l&&r>=tree[rt].r)
return tree[rt].gcd;
int mid=(tree[rt].l+tree[rt].r)>>1;
int r1=0,r2=0;
if(l<=mid) r1=find(rt<<1,l,r);
if(r>mid) r2= find(rt<<1|1,l,r);
//这里要查的区间不变
if(!r1) tree[rt].gcd=tree[rt<<1|1].gcd;
if(!r2) tree[rt].gcd=tree[rt<<1].gcd;
//不存在!r1&&!r2
//r=0表示没有if过
if(r1&&r2) tree[rt].gcd=gcd(r1,r2);
//·��ѹ��
return tree[rt].gcd;
}
int n,m;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;++i)cin>>a[i];
build(1,1,n);
int x,y;
while(m--)
{
cin>>x>>y;
cout<<find(1,x,y)<<endl;
}
return 0;
}
只过了前3个点,后面WA,求问是不是建树或者查询错了?
CPPvoid build(int rt,int l,int r)
{
tree[rt].l=l,tree[rt].r=r;
if(l==r)
{
tree[rt].gcd=a[l];
return;
}
int mid=(l+r)>>1;
build(LS);build(RS);
PushUp;
}
int find(int rt,int l,int r)
{
if(l<=tree[rt].l&&r>=tree[rt].r)
return tree[rt].gcd;
int mid=(tree[rt].l+tree[rt].r)>>1;
int r1=0,r2=0;
if(l<=mid) r1=find(rt<<1,l,r);
if(r>mid) r2= find(rt<<1|1,l,r);
//这里要查的区间不变
if(!r1) tree[rt].gcd=tree[rt<<1|1].gcd;
if(!r2) tree[rt].gcd=tree[rt<<1].gcd;
//不存在!r1&&!r2
//r=0表示没有if过
if(r1&&r2) tree[rt].gcd=gcd(r1,r2);
//自以为是的路径压缩
return tree[rt].gcd;
}
BigYellowDog
回复
共 21 条回复,欢迎继续交流。
正在加载回复...