萌新求调分块MLE
查看原帖
萌新求调分块MLE
311306
dk_qwq楼主2023/8/28 20:31

RT

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
namespace INPUT{
    char buf[1<<20],*p1,*p2;
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
}
using namespace INPUT;
template<typename T>
inline T read(){
    T x=0,p=1;
    char ch=gc();
    for(;ch<'0'||ch>'9';ch=gc())
        if(ch=='-') p=-1;
    for(;ch>='0'&&ch<='9';ch=gc())
        x=(x<<3)+(x<<1)+(ch^48);
    return x*p;
}
#pragma GCC optimize(2)
const int N=100005,M=350;
#define B 333
int pos[N],DL[M],DR[M];
int fa[M][N],siz[M][N];
int find(int p,int x) {
    return fa[p][x]==x?x:fa[p][x]=find(p,fa[p][x]);
}
void Union(int p,int u,int v){
    u=find(p,u),v=find(p,v);
    fa[p][v]=u,siz[p][u]+=siz[p][v];
}
int n,m,a[N];
int LazyTag[M];
int Mx[M];
vector<int>vals[M];
void build(int p,int l=1,int r=n,int x=1e9){
    //可能存在经过change改变postion导致为清空的行为
    for(int i=DL[p];i<=DR[p];i++) a[i]=find(p,a[i]);
    for(auto v:vals[p]) fa[p][v]=v,siz[p][v]=0;
    vals[p].clear();
    Mx[p]=0;
    for(int i=DL[p];i<=DR[p];i++){
        a[i]+=LazyTag[p];
        if(l<=i&&i<=r&&a[i]>x) a[i]-=x;
        Mx[p]=max(Mx[p],a[i]);
        if(!siz[p][a[i]]) vals[p].push_back(a[i]);
        siz[p][a[i]]++;
    }
    LazyTag[p]=0;
}
void Change(int p,int x){
    if(Mx[p]<=x) return ;
    if(2*x>=Mx[p]){
        for(int i=x+1-LazyTag[p];i<=Mx[p]-LazyTag[p];i++){
            if(find(p,i)==i&&!siz[p][i]) continue;
            if(!siz[p][i-x]) vals[p].push_back(i-x);
            Union(p,i-x,i);
        }
        
        Mx[p]=0;
        for(int i=1-LazyTag[p];i<=x-LazyTag[p];i++)
            if(siz[p][i]) Mx[p]=max(Mx[p],find(p,i)+LazyTag[p]);

    }
    else {
        for(int i=1-LazyTag[p];i<=min(Mx[p]-LazyTag[p],x-LazyTag[p]);i++){
            if(find(p,i)==i&&!siz[p][i]) continue;
            if(!siz[p][i+x]) vals[p].push_back(i+x);
            Union(p,i+x,i);
        }
        Mx[p]-=x;//WA!!!!!!???????????
        if(Mx[p]<x)
            for(int i=1-LazyTag[p];i<=x-LazyTag[p];i++)
                if(siz[p][i]) Mx[p]=max(Mx[p],find(p,i)+LazyTag[p]);
        LazyTag[p]-=x;
    }
}
void Change(int l,int r,int x){
    int L=pos[l],R=pos[r];
    if(L+1<=R){
        build(L,l,DR[L],x),build(R,DL[R],r,x);
        for(int i=L+1;i<=R-1;i++) Change(i,x);
    }
    else build(L,l,r,x);
}
int Query(int p,int l,int r,int x){
    int ans=0;
    for(int i=l;i<=r;i++)
        if(find(p,a[i])+LazyTag[p]==x) ans++;
    return ans;
}
int Query(int l,int r,int x){
    int L=pos[l],R=pos[r];
    int ans=0;
    if(L+1<=R){
        ans+=Query(L,l,DR[L],x),ans+=Query(R,DL[R],r,x);
        for(int i=L+1;i<=R-1;i++) 
            if(find(i,x-LazyTag[i])==x-LazyTag[i]) ans+=siz[i][find(i,x-LazyTag[i])];
    }
    else ans+=Query(L,l,r,x);
    return ans;
}
int main(){
    //    freopen("CF896E.in","r",stdin);
    //    freopen("CF896E.out","w",stdout);
    n=read<int>(),m=read<int>();
    for(int i=1;i<=n;i++) pos[i]=(i-1)/B+1;
    int sz=(n-1)/B+1;
    for(int i=1;i<=sz;i++)
        DL[i]=(i-1)*B+1,DR[i]=min(i*B,n);
    for(int i=1;i<=n;i++) a[i]=read<int>();
    for(int i=1;i<=sz;i++)
        for(int v=1;v<=1e5;v++) fa[i][v]=v;
    for(int i=1;i<=sz;i++) build(i);

    int op,l,r,x;
    for(int i=1;i<=m;i++){
        op=read<int>();
        l=read<int>(),r=read<int>(),x=read<int>();

        if(op==1) Change(l,r,x);
        if(op==2) printf("%d\n",Query(l,r,x));
    }
}

2023/8/28 20:31
加载中...