平衡树+线段树15pts求调
查看原帖
平衡树+线段树15pts求调
550575
Wang_Wenhan楼主2024/10/3 17:09
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n,m;
int a[N];
vector<int> v;

namespace segment{
    struct stu{
        long long val;
    }tree[N<<2];
    int ls(int xx){
        return xx*2;
    }
    int rs(int xx){
        return xx*2+1;
    }
    void pushup(int x){
        tree[x].val=tree[ls(x)].val+tree[rs(x)].val;
    }
    void build(int now,int l,int r){
        if(l==r){
            tree[now].val=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(ls(now),l,mid);
        build(rs(now),mid+1,r);
        pushup(now);
    }
    void update(int now,int l,int r,int pla,int val){
        if(l==r && l==pla){
            tree[now].val+=val;
            return;
        }
        int mid=(l+r)>>1;
        if(pla<=mid) update(ls(now),l,mid,pla,val);
        else update(rs(now),mid+1,r,pla,val);
        pushup(now);
    }
    long long query(int now,int l,int r,int ll,int rr){
        if(l>=ll && r<=rr){
            return tree[now].val;
        }
        int mid=(l+r)>>1;
        long long res=0;
        if(ll<=mid) res+=query(ls(now),l,mid,ll,rr);
        if(rr>mid) res+=query(rs(now),mid+1,r,ll,rr);
        return res;
    }
}
int root[500010];
namespace treap{
    int tot;
    struct node{
        int lc,rc,val,rnk,size;
    }tree[N*200];
    void update(int k){
        tree[k].size=tree[tree[k].lc].size+tree[tree[k].rc].size+1;
    }
    void split(int k,int &a,int &b,int val){
        if(k==0){
            a=b=0;
            return;
        }
        else if(tree[k].val<=val){
            a=k;
            split(tree[k].rc,tree[k].rc,b,val);
        }
        else{
            b=k;
            split(tree[k].lc,a,tree[k].lc,val);
        }
        update(k);
        return;
    }
    void merge(int &k,int a,int b){
        if(a==0 || b==0){
            k=a+b;
            return;
        }
        else if(tree[a].rnk<=tree[b].rnk){
            k=a;
            merge(tree[k].rc,tree[k].rc,b);
        }
        else{
            k=b;
            merge(tree[k].lc,a,tree[k].lc);
        }
        update(k);
        return;
    }
    int add_node(int val){
        tree[++tot].val=val;
        tree[tot].lc=tree[tot].rc=0;
        tree[tot].size=1;
        tree[tot].rnk=rand();
        return tot;
    }
    void insert(int &k,int val){
        int a,b,cur;
        split(k,a,b,val);
        cur=add_node(val);
        merge(a,a,cur);
        merge(k,a,b);
        return;
    }
    void pre_treap(){
        for(int i=1;i<=n;i++){
            for(int j=2;j<=sqrt(a[i]);j++){
                if(!(a[i]%j)){
                    insert(root[j],i);
                    //cout<<"fk: "<<i<<" "<<j<<"\n";
                    if((j*j)!=a[i]){
                        //cout<<"fk: "<<i<<" "<<j<<"\n";
                        insert(root[a[i]/j],i);
                    }
                }
            }
            insert(root[a[i]],i);
        }
    }
    void dfs(int now,int x){
        //cout<<"fuck: "<<tree[now].val<<"\n";
        if(!now) return;
        if(!(a[tree[now].val]%x)) v.push_back(now);//,cout<<"yes: "<<tree[now].val<<"\n"
        dfs(tree[now].lc,x);
        dfs(tree[now].rc,x);
    }
    int get(int x){
        return tree[x].val;
    }
    void work(int l,int r,int x){
        int a,b,c;
        split(root[x],a,b,l-1);
        split(b,b,c,r);
        merge(a,a,c);
        dfs(b,x);
        root[x]=a;
    }
}

inline int read(){
    char ch;int x=0;bool f=false;
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=true;
    for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
    if(f) x=-x;
    return x;
}

void work(int opt,int l,int r,int x){
    if(x==1) return;
    else{
        v.clear();
        treap::work(l,r,x);
        if(!v.size()) return;
        //cout<<"size: "<<v.size()<<"\n";
        for(int i=0;i<v.size();i++){
            int ops=v[i];
            //cout<<"val: "<<treap::get(ops)<<" "<<(a[treap::get(ops)]/x)-a[treap::get(ops)]<<"\n";
            segment::update(1,1,n,treap::get(ops),(a[treap::get(ops)]/x)-a[treap::get(ops)]);
            a[treap::get(ops)]/=x;
            if(!(a[treap::get(ops)]%x)) treap::insert(root[x],ops);
        }
        return;
    }
}

int main(){
    srand(time(0));
    //freopen("check.in","r",stdin);
    //freopen("myans.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    segment::build(1,1,n);
    treap::pre_treap();
    int opt,l,r,x;
    while(m--){
        opt=read(),l=read(),r=read();
        if(opt==1){
            x=read();
            work(opt,l,r,x);
        }
        else{
            cout<<segment::query(1,1,n,l,r)<<"\n";
        }
    }
    return 0;
}
/*
5 2
99999 99999 100000 100000 100000
1 1 5 2
2 1 5
*/
2024/10/3 17:09
加载中...