一维差分/二维差分/ 三维差分/ 树上差分
一维差分:
- 比较容易理解, 就是每一个单位元素和前面一个元素的差值,通过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值,后面是加减的值的正负。
区间修改: 和上面同理,不过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;
}
例题:

试题 历届真题 三体攻击【第九届】【省赛】【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>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
没有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;
}