P9989 [Ynoi Easy Round 2023] TEST_69 思考记录

Part.1 思路:

第一道 Ynoi!!!!

最初拿到这道题,思路非常明确,我们注意到这道题与 P4145 的解题思路类似,P4145 运用了 \(\sqrt{x}\) 缩小极快的性质,我们只需维护区间和,区间 max,每次在合适的位置进行剪枝,再暴力开方即可。

void change(int x,int l,int r) {
    if(tree[x].ma<=1) {
        return;
    }
    if(tree[x].l==tree[x].r) {
        tree[x].k=tree[x].ma=sqrt(tree[x].k);
        return;
    }
    int mid=(tree[x].l+tree[x].r)>>1;
    if(l<=mid) {
        change(lc(x),l,r);
    }
    if(r>mid) {
        change(rc(x),l,r);
    }
    pushup(x);
}

这就是最重要的修改代码,非常简单易懂。

但是这道题与 P4145 并不相同,\(\gcd{x}\) 相对于 \(\sqrt{x}\) 更加难以维护(其实是废话)。但,我们注意到,\(\gcd{x}\) 每次操作结束后,都必定还是 \(x\) 的因数,所以我们可以发现,\(x\) 的变化次数不会超过它的 因数个数,复杂度是 \(\log{x}\) 的,我们可以抓住这个性质找到突破口。

简单的说,我们只需要维护区间 \(lcm\),每次递归判断 \(x\) 能否整除区间 \(lcm\) 如果能,直接结束递归就行了,因为此时继续 \(\gcd\) 这个区间内的数值也不会有任何变化了。

不是,这真这么简单吗?

Part.2 代码实现:

首先,我们用结构体封装线段树的主题。

struct node {
    int l,r,k,lm;
}tree[N<<2];
//注意线段树要开四倍空间。

接着,pushup 和建树也没有什么可以说的。

void pushup(int x) {
    tree[x].k=(tree[lc(x)].k+tree[rc(x)].k)%mod;
    //注意取模。
    tree[x].lm=lcm(tree[lc(x)].lm,tree[rc(x)].lm);
}
void build(int x,int l,int r) {
    tree[x].l=l;
    tree[x].r=r;
    if(l==r) {
        tree[x].k=tree[x].lm=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(lc(x),l,mid);
    build(rc(x),mid+1,r);
    pushup(x);
}

change 函数相比 P4145,唯一的区别就是将剪枝的部分修改一下,其他部分几乎不变。

void change(int x,int l,int r,int v) {
    if(v%tree[x].lm==0) {
        return;
    }
    if(tree[x].l==tree[x].r) {
        tree[x].lm=gcd(tree[x].lm,v);
        tree[x].k=tree[x].lm%mod;
        return;
    }
    int mid=(tree[x].l+tree[x].r)>>1;
    if(l<=mid) {
        change(lc(x),l,r,v);
    }
    if(r>mid) {
        change(rc(x),l,r,v);
    }
    pushup(x);
}

查询操作就是最普通的求区间和,这个不多说。

int query(int x,int l,int r) {
    if(l<=tree[x].l&&tree[x].r<=r) {
        return tree[x].k;
    }
    int z=0,mid=(tree[x].l+tree[x].r)>>1;
    if(l<=mid) {
        z+=query(lc(x),l,r)%mod;
    }
    if(r>mid) {
        z+=query(rc(x),l,r)%mod;
    }
    return z%mod;
}

在经过以上所有的步骤后,你会得到这个

我也是能切 Ynoi 的人了!!!!

posted @ 2026-06-03 21:33  Lemon_eggplant  阅读(5)  评论(0)    收藏  举报