• 基础数据结构练习题


    sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧。

    在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手。于是她的好朋友九条可怜酱给她出了一道题。

    给出一个长度为 nn 的数列 AA,接下来有 mm 次操作,操作有三种:

    1. 对于所有的 i[l,r]i∈[l,r],将 AiAi 变成 Ai+xAi+x。
    2. 对于所有的 i[l,r]i∈[l,r],将 AiAi 变成 Ai−−√⌊Ai⌋。
    3. 对于所有的 i[l,r]i∈[l,r],询问 AiAi 的和。

    作为一个不怎么熟练的初学者,sylvia 想了好久都没做出来。而可怜酱又外出旅游去了,一时间联系不上。于是她决定向你寻求帮助:你能帮她解决这个问题吗。

    输入格式

    第一行两个数:n,mn,m。

    接下来一行 nn 个数 AiAi。

    接下来 mm 行中,第 ii 行第一个数 titi 表示操作类型:

    若 ti=1ti=1,则接下来三个整数 li,ri,xili,ri,xi,表示操作一。

    若 ti=2ti=2,则接下来三个整数 li,rili,ri,表示操作二。

    若 ti=3ti=3,则接下来三个整数 li,rili,ri,表示操作三。

    输出格式

    对于每个询问操作,输出一行表示答案。

    样例一

    input

    5 5
    1 2 3 4 5
    1 3 5 2
    2 1 4
    3 2 4
    2 3 5
    3 1 5
    
    

    output

    5
    6
    

    题解:  其实这个题是随便写的,举个栗子   100  20-->10 4--->3  2----> 1 1,所以我们可以猜个结论,就是在我们可以接受次的开根号这个序列趋于相同

    要是这个区间的差大于1我们就暴力dfs修改,我们可以感性的知道肯定不会修改很多次,对于这个区间:  如果  maxn-minn==0,就相当于区间覆盖,

    对于3 4,开根号后变成了1 2,他们的 maxn-minn还是等于1,这样子相当于一个区间加减,然后总之就是一个双标记的问题。

    hint:  应该在putdown的时候更新左右孩子的信息。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=100000*5;
    long long setv[N],maxv[N],minv[N],addv[N],a[N],sumv[N];
    long long _max,_min,_sum;
    long long n,m;
    long long w;
    void build(long long o,long long l,long long r)
    {
        if(l==r)
        {
            sumv[o]=maxv[o]=minv[o]=a[l];
            return;
        }
        long long mid=(r+l)/2;
        build(o*2,l,mid);
        build(o*2+1,mid+1,r);
        sumv[o]=sumv[o*2+1]+sumv[o*2];
        maxv[o]=max(maxv[o*2],maxv[o*2+1]);
        minv[o]=min(minv[o*2],minv[o*2+1]);
    }
    void query(long long o,long long l,long long r,long long ql,long long qr,long long add)
    {
        if(setv[o]>0)
        {
            _sum+=(setv[o]+add)*(long long)(min(qr,r)-max(ql,l)+1);
        }
        else if(ql<=l&&qr>=r)
        {
            _sum+=sumv[o]+(add)*(long long)(r-l+1);
        }
        else
        {
            int mid=(l+r)/2;
            if(ql<=mid) query(o*2,l,mid,ql,qr,add+addv[o]);
            if(qr>mid) query(o*2+1,mid+1,r,ql,qr,add+addv[o]);
        }
    }
    void maintain(int o,int l,int r)
    {
        int lc=o*2,rc=o*2+1;
        if(setv[o]!=0)
        {
            sumv[o]=setv[o]*(r-l+1);
            maxv[o]=setv[o]; minv[o]=setv[o];
        }
        else
        {
            if(r>l){
            sumv[o]=sumv[rc]+sumv[lc]+addv[o]*(r-l+1);
            maxv[o]=max(maxv[rc],maxv[lc])+addv[o];
            minv[o]=min(minv[rc],minv[lc])+addv[o];}
        }
    }
    void Puttage(int o,int l,int r)
    {
         int mid=(l+r)/2;
         int lc=o*2,rc=o*2+1;
         if(r>l){
         int lc=o*2,rc=o*2+1;
         if(setv[o]!=0)
         {
             setv[o*2]=setv[o];  setv[o*2+1]=setv[o];
             addv[rc]=addv[lc]=0;
             sumv[lc]=setv[lc]*(mid-l+1);
             maxv[lc]=setv[lc];  minv[lc]=setv[lc];
             sumv[rc]=setv[rc]*(r-mid);
             maxv[rc]=setv[rc];  minv[rc]=setv[rc];
             setv[o]=0;
         }
         else
         {
             if(setv[rc]!=0) {setv[rc]+=addv[o]; sumv[rc]=setv[rc]*(r-mid);  maxv[rc]=setv[rc];  minv[rc]=setv[rc];}
             else {addv[rc]+=addv[o]; sumv[rc]=sumv[rc]+addv[o]*(r-mid);  maxv[rc]=maxv[rc]+addv[o];  minv[rc]=minv[rc]+addv[o];}
             if(setv[lc]!=0) {setv[lc]+=addv[o]; sumv[lc]=setv[lc]*(mid-l+1);  maxv[lc]=setv[lc];  minv[lc]=setv[lc];}
             else {addv[lc]+=addv[o]; sumv[lc]=sumv[lc]+addv[lc]*(l-mid+1); maxv[lc]=maxv[lc]+addv[o]; minv[lc]=minv[lc]+addv[o];}
             addv[o]=0;
         }}
    }
    void change(int x,int l,int r,int ql,int qr,int k)
    {
        if(ql>r||qr<l) return;
        if(ql<=l&&qr>=r)
        {
            if(l==r)
            {
                if(setv[x]==0) a[l]+=addv[x];
                else a[l]=setv[x];
                setv[x]=addv[x]=0;
                if(k==1)
                {
                    a[l]+=w;
                    sumv[x]=a[l];
                    maxv[x]=a[l]; minv[x]=a[l];
                    return;
                }
                else
                {
                    a[l]=(int)sqrt(a[l]);
                    sumv[x]=a[l];
                    maxv[x]=a[l]; minv[x]=a[l];
                    return;
                }
            }
            if(k==1)
            {
                if(setv[x]>0)
                {
                    setv[x]+=w;
                    maintain(x,l,r);
                    return;
                }
                else
                {
                    addv[x]+=w;
                    maintain(x,l,r);
                    return;
                }
            }
            else
            {
                _max=maxv[x];  _min=minv[x];
                if(_max==_min)
                {
                    int temp=(int)sqrt(_min);
                    setv[x]=temp;
                    if(addv[x]!=0) addv[x]=0;
                    maintain(x,l,r);
                    return;
                }
                else
                {
                    if(_max-_min==1)
                    {
                        int temp=(int)sqrt(_max);
                        int temp2=(int)sqrt(_min);
                        if(temp-temp2==1)
                        {
                            addv[x]-=_max-temp;
                            maintain(x,l,r);
                            return;
                        }
                        else if(temp-temp2==0)
                        {
                            setv[x]=temp;
                            if(addv[x]!=0) addv[x]=0;
                            maintain(x,l,r);
                            return;
                        }
                        else
                        {
                            Puttage(x,l,r);
                            int mid=(r+l)/2;
                            maintain(x*2,l,mid);
                            maintain(x*2+1,mid+1,r);
                        }
                    }
                    else
                    {
                        Puttage(x,l,r);
                        int mid=(r+l)/2;
                        maintain(x*2,l,mid);
                        maintain(x*2+1,mid+1,r);
                    }
                }
            }
        }
        else
        {
            Puttage(x,l,r);
            int mid=(r+l)/2;
            maintain(x*2,l,mid);
            maintain(x*2+1,mid+1,r);
        }
        int mid=(r+l)/2;
        change(x*2,l,mid,ql,qr,k);
        change(x*2+1,mid+1,r,ql,qr,k);
        maintain(x,l,r);
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            int t;
            int ql,qr;
            scanf("%d",&t);
            if(t==1)
            {
                scanf("%d%d%lld",&ql,&qr,&w);
                change(1,1,n,ql,qr,1);
            }
            else if(t==2)
            {
                scanf("%d%d",&ql,&qr);
                change(1,1,n,ql,qr,2);
            }
            else
            {
                _sum=0;
                scanf("%d%d",&ql,&qr);
                query(1,1,n,ql,qr,0);
                printf("%lld
    ",_sum);
            }
        }
      //  return 0;
    }
    //3802450110
    

      

  • 相关阅读:
    css定位
    css遗漏
    php字符操作
    php类于对象
    php数组的操作
    php基础
    javascript显式类型的转换
    【模板】并查集
    图论三种做法:朴素版Dijkstra、堆优化(优先队列)Dijkstra、spfa(队列优化版Bellman-Ford)
    二分之一网打尽
  • 原文地址:https://www.cnblogs.com/Heilce/p/7220905.html
Copyright © 2020-2023  润新知