• [YNOI2018]五彩斑斓的世界&CF896E(分块+并查集)


    由于晚上比赛二连(Atcoder&codeforces),外加复习学考,所以暂时没时间写了。

    贴个O(n√n)的分块代码,洛谷和cf上都过了,但垃圾bzoj卡不过去,不改了。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    int n,m,B,a[N],b[N],pos[N],l[N],r[N],fa[N],mx[N],sum[N],c[320][N],tag[N];
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void build(int id)
    {
        for(int i=l[id];i<=r[id];i++)a[i]=b[find(i)],c[id][a[i]]=0;
        for(int i=l[id];i<=r[id];i++)fa[i]=i,sum[i]=1;
        for(int i=l[id];i<=r[id];i++)
        if(!c[id][a[i]])c[id][a[i]]=i,b[i]=a[i];
        else sum[c[id][a[i]]]+=sum[i],fa[i]=c[id][a[i]];
        while(!c[id][mx[id]])mx[id]--;
    }
    void update(int id,int x,int y,int v)
    {
        for(int i=l[id];i<=r[id];i++)a[i]=b[find(i)];
        for(int i=l[id];i<=r[id];i++)c[id][a[i]]=0;
        for(int i=x;i<=y;i++)if(b[find(i)]-tag[id]>v)a[i]-=v;
        for(int i=l[id];i<=r[id];i++)b[i]=a[i],fa[i]=i;
        build(id);
    }
    void modify(int x,int y,int v)
    {
        if(pos[x]==pos[y]){update(pos[x],x,y,v);return;}
        update(pos[x],x,r[pos[x]],v),update(pos[y],l[pos[y]],y,v);
        for(int i=pos[x]+1;i<pos[y];i++)
        if(v<mx[i]-tag[i]&&mx[i]-tag[i]<2*v)
        {
            for(int j=tag[i]+v+1;j<=mx[i];j++)
            if(c[i][j])
                if(!c[i][j-v])c[i][j-v]=c[i][j],b[c[i][j]]=j-v,c[i][j]=0;
                else fa[c[i][j]]=c[i][j-v],sum[c[i][j-v]]+=sum[c[i][j]],c[i][j]=0;
            while(!c[i][mx[i]])mx[i]--;
        }
        else if(mx[i]-tag[i]>=2*v)
        {
            for(int j=tag[i]+1;j<=tag[i]+v;j++)
            if(c[i][j])
                if(!c[i][j+v])c[i][j+v]=c[i][j],b[c[i][j]]=j+v,c[i][j]=0;
                else fa[c[i][j]]=c[i][j+v],sum[c[i][j+v]]+=sum[c[i][j]],c[i][j]=0;
            tag[i]+=v;
        }
    }
    int query(int x,int y,int v)
    {
        int ret=0;
        if(pos[x]==pos[y])
        {
            for(int i=x;i<=y;i++)if(b[find(i)]-tag[pos[i]]==v)ret++;
            return ret;
        }
        for(int i=x;i<=r[pos[x]];i++)if(b[find(i)]-tag[pos[i]]==v)ret++;
        for(int i=l[pos[y]];i<=y;i++)if(b[find(i)]-tag[pos[i]]==v)ret++;
        for(int i=pos[x]+1;i<pos[y];i++)if(v+tag[i]<N)ret+=sum[c[i][v+tag[i]]];
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m),B=sqrt(n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i],fa[i]=i;
        for(int i=1;i<=n;i++)
        {
            r[pos[i]=(i-1)/B+1]=i;
            if(!l[pos[i]])l[pos[i]]=i;
        }
        for(int i=1;i<=pos[n];i++)mx[i]=1e5,build(i);
        while(m--)
        {
            int op,x,y,v;scanf("%d%d%d%d",&op,&x,&y,&v);
            if(op==1)modify(x,y,v);else printf("%d
    ",query(x,y,v));
        }
    }
    View Code
  • 相关阅读:
    javaScript设计模式:装饰模式
    搭建自动签到服务
    Gmail邮箱注册
    springcloud3(六) 服务降级限流熔断组件Resilience4j
    PCB
    行业_激光
    Git设置Http代理,克隆github上的代码
    工控机与运动控制卡
    锂电池生产工艺
    PCB涂胶工艺
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10960531.html
Copyright © 2020-2023  润新知