• 一维差分/二维差分/ 三维差分 (通俗易懂)


      一维差分:

    • 比较容易理解, 就是每一个单位元素和前面一个元素的差值,通过O(n) 时间复杂度 就可以把这个队列里面的值给弄出啦。
    • 用于解决很多次修改区间问题

      二维差分:

    • 同理可得,不过的单位元素的差值= val【I】[J] - val【I】[J-1] - VAL[I-1][J]+VAL[I-1][J-1] ;    建议自己简单画一个图来进行理解
    • O(n) 推导的时候  就 单位元素的差值+= val【I】[J-1] +VAL[I-1][J]-VAL[I-1][J-1] ; 
    • 在进行 矩形区间修改的时候就这样:(+2) 表示差分数组的值+2;

            为什么?

    • 考虑 3 个关键元素 :单位元素的差值+= val【I】[J-1] +VAL[I-1][J]-VAL[I-1][J-1] ;  就是这个等号右边的3个元素
    • 选择一个修改区间外的方块, 看他的 3个关键元素有没有在 修改区间内,
    • 如果在内,看他对上面这个等式的影响,然后 单位元素的差值 加上影响的相反数即可。

        三维差分:

    • 同理可得,单位元素的差值= val【I】[J] [z] - val【I】[J-1] [z] - VAL[I-1][J][z]+VAL[I-1][J-1] -val[i][j][Z-1]+VAL[I-1][J][Z-1]+VAL[[I][J-1][Z-1]-VAL[I-1][J-1][Z-1]; 
    • 求差分

        关键:  偶数个 1 的 符号一致, 奇数个1 符号和 前面的偶数符号相反。(通过 0,0,0的来确认符号)

    const int  d[8][4] = {
             {0,0,0,1},
        {0,0,-1,-1},
        {0,-1,0,-1},
             {0,-1,-1,1},
        {-1,0,0,-1},
        {-1,0,-1,1},
        {-1,-1,0,1},
        {-1,-1,-1,-1}
    };
    
    二进制 8 , 前面是 代表xyz值,后面是加减的值的正负。
    View Code

         区间修改: 和上面同理,不过1 变成 R+1, 

        for(ri i=1;i<=mid;i++)
        {
            b[get(p[i].la,p[i].lb,p[i].lc)]-=p[i].val;
            b[get(p[i].la,p[i].lb,p[i].rc+1)]+=p[i].val;
            b[get(p[i].la,p[i].rb+1,p[i].lc)]+=p[i].val;
            b[get(p[i].la,p[i].rb+1,p[i].rc+1)]-=p[i].val;
            b[get(p[i].ra+1,p[i].lb,p[i].lc)]+=p[i].val;
            b[get(p[i].ra+1,p[i].rb+1,p[i].lc)]-=p[i].val;
            b[get(p[i].ra+1,p[i].lb,p[i].rc+1)]-=p[i].val;
            b[get(p[i].ra+1,p[i].rb+1,p[i].rc+1)]+=p[i].val;
        }
    View Code

     

    例题:

    试题 历届真题 三体攻击【第九届】【省赛】【A组】
         
    资源限制
    内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s
    问题描述
      三体人将对地球发起攻击。为了抵御攻击,地球人派出了 A × B × C 艘战舰,在太空中排成一个 A 层 B 行 C 列的立方体。其中,第 i 层第 j 行第 k 列的战舰(记为战舰 (i, j, k))的生命值为 d(i, j, k)。
    
      三体人将会对地球发起 m 轮“立方体攻击”,每次攻击会对一个小立方体中的所有战舰都造成相同的伤害。具体地,第 t 轮攻击用 7 个参数 lat, rat, lbt, rbt, lct, rct, ht 描述;
      所有满足 i ∈ [lat, rat],j ∈ [lbt, rbt],k ∈ [lct, rct] 的战舰 (i, j, k) 会受到 ht 的伤害。如果一个战舰累计受到的总伤害超过其防御力,那么这个战舰会爆炸。
    
      地球指挥官希望你能告诉他,第一艘爆炸的战舰是在哪一轮攻击后爆炸的。
    输入格式
      从标准输入读入数据。
    
      第一行包括 4 个正整数 A, B, C, m;
      第二行包含 A × B × C 个整数,其中第 ((i − 1)×B + (j − 1)) × C + (k − 1)+1 个数为 d(i, j, k);
      第 3 到第 m + 2 行中,第 (t − 2) 行包含 7 个正整数 lat, rat, lbt, rbt, lct, rct, ht。
    输出格式
      输出到标准输出。
    
      输出第一个爆炸的战舰是在哪一轮攻击后爆炸的。保证一定存在这样的战舰。
    样例输入
    2 2 2 3
    1 1 1 1 1 1 1 1
    1 2 1 2 1 1 1
    1 1 1 2 1 2 1
    1 1 1 1 1 1 2
    样例输出
    2
    样例说明
      在第 2 轮攻击后,战舰 (1,1,1) 总共受到了 2 点伤害,超出其防御力导致爆炸。
    数据约定
      对于 10% 的数据,B = C = 1;
      对于 20% 的数据,C = 1;
      对于 40% 的数据,A × B × C, m ≤ 10, 000;
      对于 70% 的数据,A, B, C ≤ 200;
      对于所有数据,A × B × C ≤ 10^6, m ≤ 10^6, 0 ≤ d(i, j, k), ht ≤ 10^9。
    
    
      资源约定:
      峰值内存消耗(含虚拟机) < 256M
      CPU消耗 < 2000ms
    
    
      请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
    
      注意:
      main函数需要返回0;
      只使用ANSI C/ANSI C++ 标准;
      不要调用依赖于编译环境或操作系统的特殊函数。
      所有依赖的函数必须明确地在源文件中 #include <xxx>
      不能通过工程设置而省略常用头文件。
    
      提交程序时,注意选择所期望的语言类型和编译器类型。
    三体攻击【第九届】【省赛】【A组】

    没有AC的代码,最后一个时间超时,qwq,全网找了很久每找到一个AC的,哎

    思路,二分答案+差分

    #include <bits/stdc++.h>
    using namespace std;
    #define ri register int
    #define M 2000050
    
    
    template <class G >  void read(G &x)
    {
        x=0;int f=0;char ch=getchar();
        while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x=f?-x:x;
        return ;
    }
    int A,B,C,m;
    int get(int a,int b,int c)
    {
        return (a*B+b)*C+c;
    }
    int xf[M],b[M];
    const int  d[8][4] = {
        {0,0,0,1},
        {0,0,-1,-1},
        {0,-1,0,-1},
        {0,-1,-1,1},
        {-1,0,0,-1},
        {-1,0,-1,1},
        {-1,-1,0,1},
        {-1,-1,-1,-1}
    };
    int val[M];
    
    struct dian{
        int la,ra,lb,rb,lc,rc,val;
    }p[M];
    int op[9];
    
    void init()
    {
            for(ri i=1;i<=A;i++)
            {
              for(ri j=1;j<=B;j++)
               {
                for(ri k=1;k<=C;k++)
                {
                  b[get(i,j,k)]=xf[get(i,j,k)];
                  val[get(i,j,k)]=0; //
                }
               }
            }
    }
    bool ck(int mid)
    {
        init();
        for(ri i=1;i<=mid;i++)
        {
            b[get(p[i].la,p[i].lb,p[i].lc)]-=p[i].val;
            b[get(p[i].la,p[i].lb,p[i].rc+1)]+=p[i].val;
            b[get(p[i].la,p[i].rb+1,p[i].lc)]+=p[i].val;
            b[get(p[i].la,p[i].rb+1,p[i].rc+1)]-=p[i].val;
            b[get(p[i].ra+1,p[i].lb,p[i].lc)]+=p[i].val;
            b[get(p[i].ra+1,p[i].rb+1,p[i].lc)]-=p[i].val;
            b[get(p[i].ra+1,p[i].lb,p[i].rc+1)]-=p[i].val;
            b[get(p[i].ra+1,p[i].rb+1,p[i].rc+1)]+=p[i].val;
        }
        for(ri i=1;i<=A;i++)
        {
            for(ri j=1;j<=B;j++)
            {
                for(ri k=1;k<=C;k++)
                {
                    int  tmp=0;
                    for(ri cur=1;cur<=7;cur++) // zhu yi shu zhu d fan wei 
                    {
                        int x=i+d[cur][0],y=j+d[cur][1],z=k+d[cur][2],h=d[cur][3];
                        tmp+=val[get(x,y,z)]*h;
                    }
                    val[get(i,j,k)]=b[get(i,j,k)]-tmp;
                    if(val[get(i,j,k)]<0) 
                    {
                        return 1;
                    }
                }
            }
        }
        return 0;
        
        
    }
    int main(){
        
        read(A);read(B);read(C);read(m);
        for(ri i=1;i<=A;i++)
        {
            for(ri j=1;j<=B;j++)
            {
                for(ri k=1;k<=C;k++)
                {
                    read(val[get(i,j,k)]);
                }
            }
        }
        
        for(ri i=1;i<=A;i++)
        {
            for(ri j=1;j<=B;j++)
            {
                for(ri k=1;k<=C;k++)
                {
                    int  tmp=0;
                    for(ri cur=0;cur<=7;cur++) // zhu yi shu zhu d fan wei 
                    {
                        int x=i+d[cur][0],y=j+d[cur][1],z=k+d[cur][2],h=d[cur][3];
                        tmp+=val[get(x,y,z)]*h;
                    }
                   xf[get(i,j,k)]=tmp;
                }
            }
        }
        for(ri i=1;i<=m;i++)
        {
            read(op[1]);read(op[2]);read(op[3]);read(op[4]);read(op[5]);read(op[6]);read(op[7]);
            p[i].la=op[1];p[i].ra=op[2];p[i].lb=op[3];p[i].rb=op[4];p[i].lc=op[5];p[i].rc=op[6];p[i].val=op[7];
        }
        int l=1,r=m;
        
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(ck(mid)) r=mid;
            else l=mid+1;
        }
        printf("%d",r);
        return 0;
    
    }
    View Code

     

     

     

         

     

  • 相关阅读:
    python测试开发django-1.开始hello world!
    python基础--杂项
    Python基础----函数
    python介绍
    公共Webservice
    divmod(a,b)函数
    模块知识
    第三周作业 修改配置文件
    rsync在windows和linux同步数据的配置过程
    docker学习笔记
  • 原文地址:https://www.cnblogs.com/Lamboofhome/p/16092135.html
Copyright © 2020-2023  润新知