bzoj 2683 簡單題 cdq分治 樹狀陣列

2021-07-24 19:54:31 字數 1304 閱讀 1729

要求資瓷下列操作:

1 x y z把(x,y)加上z

2 x1 y1 x2 y2求矩形x1 y1 x2 y2的權值和

n<=500000,x,y<=n,q<=200000

首先可以把乙個詢問用容斥原理拆成四個詢問,然後在cdq分治中二分乙個橫座標mid,然後把操作從前往後掃一遍,若是修改操作且橫座標不大於mid則處理,若是詢問操作且橫座標大於mid則處理;然後把操作按照橫座標分成左右兩部分遞迴處理即可。

#include

#include

#include

#include

#include

#define n 500005

using namespace std;

int c[n],n,m,num,ans[n];

struct queq[n*4],tmp[n*4];

intread()

while (ch>='0'&&ch<='9')

return

x*f;

}void ins(int

x,inty)}

int query(int

x) return ans;

}void cdq(int l,int r,int l,int r)

int mid=(l+r)/2,s=0;

for (int i=l;i<=r;i++)

if (q[i].op==1)

}else

for (int i=l;i<=r;i++)

if (q[i].op==1&&q[i].x

<=mid) ins(q[i].y,-q[i].z);

int i=l,j=l+s;

for (int k=l;k<=r;k++)

if (q[k].x

<=mid) tmp[i++]=q[k];

else tmp[j++]=q[k];

for (int k=l;k<=r;k++)

q[k]=tmp[k];

cdq(l,i-1,l,mid);

cdq(i,r,mid+1,r);

}int main()

else

}cdq(1,m,1,n);

for (int i=1;i<=m;i++)

if (q[i].op==2) ans[q[i].id]+=q[i].val*q[i].ans;

for (int i=1;i<=num;i++)

printf("%d\n",ans[i]);

return

0;}

BZOJ 2683 簡單題 CDQ分治

n n矩陣,支援單點修改,查詢某乙個子矩陣內的和 n leq 500000 運算元 leq 200000 首先運用二維字首和的思想,把子矩陣的和拆成四個字首和。然後把詢問和修改看成 x,y,t 的三元組,t表示當前是第幾次操作。然後就變成三維偏序問題,對於每個詢問,找x,y,t均比它小的修改操作,再...

bzoj2683簡單題 cdq分治

time limit 50 sec memory limit 128 mb submit 1803 solved 731 submit status discuss 你有乙個n n的棋盤,每個格仔內有乙個整數,初始時的時候全部為0,現在需要維護兩種操作 命令引數限制 內容1 x y a 1 x,y ...

BZOJ 2683 簡單題(CDQ分治 容斥)

description 你有乙個n n的棋盤,每個格仔內有乙個整數,初始時的時候全部為0,現在需要維護兩種操作 1 x y a 1 x,y n,a是正整數 將格仔x,y裡的數字加上a 2 x1 y1 x2 y2 1 x1 x2 n,1 y1 y2 n 輸出x1 y1 x2 y2這個矩形內的數字和 3...