• 分块大法好


    用分快来水“xjr考考你数据结构”真是再爽不过了

    xjr考考你数据结构一:虽然有点慢(6724ms)

    #include<cstdio>
    #include<cmath>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        char ch=getchar();int sig=1,x=0;
        while(!isdigit(ch)) {if(ch=='-') sig=-1;ch=getchar();}
        while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
        return x*sig;
    }
    const int maxn=1000010;
    const int INF=1000000000;
    int n,SIZE,A[maxn];
    int bl[maxn],st[maxn],en[maxn];
    int maxv[maxn],minv[maxn],sumv[maxn];
    void recal(int x)
    {
        maxv[x]=-INF;minv[x]=INF;sumv[x]=0;
        for(int i=st[x];i<=en[x];i++)
        {
            maxv[x]=max(maxv[x],A[i]);
            minv[x]=min(minv[x],A[i]);
            sumv[x]+=A[i];
        }
    }
    int main()
    {
        n=read();SIZE=(int)sqrt(n);
        for(int i=1;i<=n;i++)
        {
            A[i]=read();
            bl[i]=(i-1)/SIZE+1;
            en[bl[i]]=i;
            if(!st[bl[i]]) st[bl[i]]=i;
        }
        for(int i=1;i<=bl[n];i++) recal(i);
        int q=read(),l,r,x,v;
        while(q--)
        {
            char tp=getchar();
            while(!isalpha(tp)) tp=getchar();
            if(tp=='Q')
            {
                l=read();r=read();
                int mx=-INF,mn=INF,sum=0;
                if(bl[l]==bl[r]) for(int i=l;i<=r;i++) mx=max(mx,A[i]),mn=min(mn,A[i]),sum+=A[i];
                else
                {
                    for(int i=l;i<=en[bl[l]];i++) mx=max(mx,A[i]),mn=min(mn,A[i]),sum+=A[i];
                    for(int i=st[bl[r]];i<=r;i++) mx=max(mx,A[i]),mn=min(mn,A[i]),sum+=A[i];
                    for(int i=bl[l]+1;i<bl[r];i++) mx=max(mx,maxv[i]),mn=min(mn,minv[i]),sum+=sumv[i];
                }
                printf("MaxNum: %d, MinNum: %d, Sum: %d
    ",mx,mn,sum);
            }
            else 
            {
                x=read();v=read();
                A[x]=v;recal(bl[x]);
            }
        }
        return 0;
    }
    View Code

    xjr考考你数据结构二:加个add标记(1342ms)

    #include<cstdio>
    #include<cmath>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        char ch=getchar();int sig=1,x=0;
        while(!isdigit(ch)) {if(ch=='-') sig=-1;ch=getchar();}
        while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
        return x*sig;
    }
    const int maxn=100010;
    const int INF=1000000000;
    int n,SIZE;
    int bl[maxn],st[maxn],en[maxn];
    long long A[maxn],maxv[maxn],minv[maxn],sumv[maxn],add[maxn];
    void recal(int x)
    {
        maxv[x]=-INF;minv[x]=INF;sumv[x]=0;
        for(int i=st[x];i<=en[x];i++)
        {
            maxv[x]=max(maxv[x],A[i]);
            minv[x]=min(minv[x],A[i]);
            sumv[x]+=A[i];
        }
    }
    int main()
    {
        n=read();SIZE=(int)sqrt(n);
        for(int i=1;i<=n;i++)
        {
            A[i]=read();
            bl[i]=(i-1)/SIZE+1;
            en[bl[i]]=i;
            if(!st[bl[i]]) st[bl[i]]=i;
        }
        for(int i=1;i<=bl[n];i++) recal(i);
        int q=read(),l,r,v;
        while(q--)
        {
            char tp=getchar();
            while(!isalpha(tp)) tp=getchar();
            if(tp=='Q')
            {
                l=read();r=read();if(l>r) swap(l,r);
                long long mx=-INF,mn=INF,sum=0;
                if(bl[l]==bl[r]) for(int i=l;i<=r;i++) mx=max(mx,A[i]+add[bl[r]]),mn=min(mn,A[i]+add[bl[r]]),sum+=A[i]+add[bl[r]];
                else
                {
                    for(int i=l;i<=en[bl[l]];i++) mx=max(mx,A[i]+add[bl[l]]),mn=min(mn,A[i]+add[bl[l]]),sum+=A[i]+add[bl[l]];
                    for(int i=st[bl[r]];i<=r;i++) mx=max(mx,A[i]+add[bl[r]]),mn=min(mn,A[i]+add[bl[r]]),sum+=A[i]+add[bl[r]];
                    for(int i=bl[l]+1;i<bl[r];i++) mx=max(mx,maxv[i]+add[i]),mn=min(mn,minv[i]+add[i]),sum+=sumv[i]+add[i]*(en[i]-st[i]+1);
                }
                printf("MaxNum: %lld, MinNum: %lld, Sum: %lld
    ",mx,mn,sum);
            }
            else 
            {
                l=read();r=read();v=read();if(l>r) swap(l,r);
                if(bl[l]==bl[r])
                {
                    for(int i=l;i<=r;i++) A[i]+=v;
                    recal(bl[l]);
                }
                else
                {
                    for(int i=l;i<=en[bl[l]];i++) A[i]+=v;
                    for(int i=st[bl[r]];i<=r;i++) A[i]+=v;
                    for(int i=bl[l]+1;i<bl[r];i++) add[i]+=v;
                    recal(bl[l]);recal(bl[r]);
                }
            }
        }
        return 0;
    }
    View Code

    xjr考考你数据结构三:换成set标记(偷懒将维护信息和传递信息写一块了),这时间(999ms)

    #include<cstdio>
    #include<cmath>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        char ch=getchar();int sig=1,x=0;
        while(!isdigit(ch)) {if(ch=='-') sig=-1;ch=getchar();}
        while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
        return x*sig;
    }
    const int maxn=100010;
    const int INF=1000000000;
    int n,SIZE;
    int bl[maxn],st[maxn],en[maxn];
    long long A[maxn],maxv[maxn],minv[maxn],sumv[maxn],set[maxn];
    void recal(int x)
    {
        if(set[x]) for(int i=st[x];i<=en[x];i++) A[i]=set[x];
        maxv[x]=-INF;minv[x]=INF;sumv[x]=0;
        for(int i=st[x];i<=en[x];i++)
        {
            maxv[x]=max(maxv[x],A[i]);
            minv[x]=min(minv[x],A[i]);
            sumv[x]+=A[i];
        }
        set[x]=0;
    }
    int main()
    {
        n=read();SIZE=(int)sqrt(n);
        for(int i=1;i<=n;i++)
        {
            A[i]=read();
            bl[i]=(i-1)/SIZE+1;
            en[bl[i]]=i;
            if(!st[bl[i]]) st[bl[i]]=i;
        }
        for(int i=1;i<=bl[n];i++) recal(i);
        int q=read(),l,r,v;
        while(q--)
        {
            char tp=getchar();
            while(!isalpha(tp)) tp=getchar();
            if(tp=='Q')
            {
                l=read();r=read();if(l>r) swap(l,r);
                long long mx=-INF,mn=INF,sum=0;
                if(bl[l]==bl[r]) 
                {
                    if(set[bl[l]]) mx=mn=set[bl[l]],sum=set[bl[l]]*(r-l+1);
                    else for(int i=l;i<=r;i++) mx=max(mx,A[i]),mn=min(mn,A[i]),sum+=A[i];
                }
                else
                {
                    if(set[bl[l]]) mx=mn=set[bl[l]],sum=set[bl[l]]*(en[bl[l]]-l+1);
                    else for(int i=l;i<=en[bl[l]];i++) mx=max(mx,A[i]),mn=min(mn,A[i]),sum+=A[i];
                    if(set[bl[r]]) mx=max(mx,set[bl[r]]),mn=min(mn,set[bl[r]]),sum+=set[bl[r]]*(r-st[bl[r]]+1);
                    else for(int i=st[bl[r]];i<=r;i++) mx=max(mx,A[i]),mn=min(mn,A[i]),sum+=A[i];
                    for(int i=bl[l]+1;i<bl[r];i++) mx=max(mx,maxv[i]),mn=min(mn,minv[i]),sum+=sumv[i];
                }
                printf("MaxNum: %lld, MinNum: %lld, Sum: %lld
    ",mx,mn,sum);
            }
            else 
            {
                l=read();r=read();v=read();if(l>r) swap(l,r);
                if(bl[l]==bl[r])
                {
                    recal(bl[l]);
                    for(int i=l;i<=r;i++) A[i]=v;
                    recal(bl[l]);
                }
                else
                {
                    recal(bl[l]);recal(bl[r]);
                    for(int i=l;i<=en[bl[l]];i++) A[i]=v;
                    for(int i=st[bl[r]];i<=r;i++) A[i]=v;
                    for(int i=bl[l]+1;i<bl[r];i++) set[i]=v,maxv[i]=minv[i]=set[i],sumv[i]=set[i]*(en[i]-st[i]+1);
                    recal(bl[l]);recal(bl[r]);
                }
            }
        }
        return 0;
    }
    View Code

     最后是我的WZJ的数据结构(十),写的我已然TAT。(1810ms)

    #include<cstdio>
    #include<cmath>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        char ch=getchar();int sig=1,x=0;
        while(!isdigit(ch)) {if(ch=='-') sig=-1;ch=getchar();}
        while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
        return x*sig;
    }
    const int maxn=100010;
    const int INF=1000000000;
    int n,SIZE;
    int bl[maxn],st[maxn],en[maxn];
    long long A[maxn],maxv[maxn],minv[maxn],sumv[maxn],set[maxn],add[maxn];
    void pushdown(int x)
    {
        if(set[x]) for(int i=st[x];i<=en[x];i++) A[i]=set[x]+add[x];
        else for(int i=st[x];i<=en[x];i++) A[i]+=add[x];
        add[x]=set[x]=0;
    }
    void recal(int x)
    {
        maxv[x]=-INF;minv[x]=INF;sumv[x]=0;
        for(int i=st[x];i<=en[x];i++)
        {
            maxv[x]=max(maxv[x],A[i]);
            minv[x]=min(minv[x],A[i]);
            sumv[x]+=A[i];
        }
    }
    int main()
    {
        n=read();int q=read();SIZE=(int)sqrt(n);
        for(int i=1;i<=n;i++)
        {
            A[i]=read();
            bl[i]=(i-1)/SIZE+1;
            en[bl[i]]=i;
            if(!st[bl[i]]) st[bl[i]]=i;
        }
        for(int i=1;i<=bl[n];i++) recal(i);
        int l,r,v;
        while(q--)
        {
            int t=read(); 
            if(t==2)
            {
                l=read();r=read();if(l>r) swap(l,r);
                long long mx=-INF,mn=INF,sum=0;
                if(bl[l]==bl[r]) 
                {
                    if(set[bl[l]]) mx=mn=set[bl[l]],sum=set[bl[l]]*(r-l+1);
                    else for(int i=l;i<=r;i++) mx=max(mx,A[i]),mn=min(mn,A[i]),sum+=A[i];
                    mx+=add[bl[l]];mn+=add[bl[l]];sum+=add[bl[l]]*(r-l+1);
                }
                else
                {
                    if(set[bl[l]]) mx=mn=set[bl[l]]+add[bl[l]],sum=(set[bl[l]]+add[bl[l]])*(en[bl[l]]-l+1);
                    else for(int i=l;i<=en[bl[l]];i++) mx=max(mx,A[i]+add[bl[l]]),mn=min(mn,A[i]+add[bl[l]]),sum+=A[i]+add[bl[l]];
                    if(set[bl[r]]) mx=max(mx,set[bl[r]]+add[bl[r]]),mn=min(mn,set[bl[r]]+add[bl[r]]),sum+=(set[bl[r]]+add[bl[r]])*(r-st[bl[r]]+1);
                    else for(int i=st[bl[r]];i<=r;i++) mx=max(mx,A[i]+add[bl[r]]),mn=min(mn,A[i]+add[bl[r]]),sum+=A[i]+add[bl[r]];
                    for(int i=bl[l]+1;i<bl[r];i++) mx=max(mx,maxv[i]),mn=min(mn,minv[i]),sum+=sumv[i];
                }
                printf("%lld %lld %lld
    ",mx,mn,sum);
            }
            else 
            {
                l=read();r=read();v=read();if(l>r) swap(l,r);
                if(bl[l]==bl[r])
                {
                    pushdown(bl[l]);
                    if(!t) for(int i=l;i<=r;i++) A[i]=v;
                    else for(int i=l;i<=r;i++) A[i]+=v;
                    recal(bl[l]);
                }
                else
                {
                    pushdown(bl[l]);pushdown(bl[r]);
                    if(!t) for(int i=l;i<=en[bl[l]];i++) A[i]=v;
                    else for(int i=l;i<=en[bl[l]];i++) A[i]+=v;
                    if(!t) for(int i=st[bl[r]];i<=r;i++) A[i]=v;
                    else for(int i=st[bl[r]];i<=r;i++) A[i]+=v;
                    if(!t) for(int i=bl[l]+1;i<bl[r];i++) add[i]=0,set[i]=v,maxv[i]=minv[i]=set[i],sumv[i]=set[i]*(en[i]-st[i]+1);
                    else for(int i=bl[l]+1;i<bl[r];i++) add[i]+=v,maxv[i]+=v,minv[i]+=v,sumv[i]+=v*(en[i]-st[i]+1);
                    recal(bl[l]);recal(bl[r]);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    input框限制只能输入正整数、字母、小数、
    css水平垂直居中
    Android开发之旅-获取地理位置的经度和纬度
    Android DDMS应用
    Android开发BUG及解决方法2
    Android开发BUG及解决方法1
    Android开发BUG及解决方法
    Android系统架构
    1.sql简介
    C语言笔试常考知识点
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4575628.html
Copyright © 2020-2023  润新知