- 这道题我曾找过许多博客,没有能AC的,故特作此文。
- 题干传送门
- 先谈谈做本题的心路历程:
- 第一眼见:哇!二维的树状数组,虽然没见过,但是貌似不难
- 此时代码
#include<bits/stdc++.h>
using namespace std;
int n,m,dis[5001][5001],a,b,c,d,t,k;
int lowbit(int x){
return x&(-x);
}
void add(int x,int y,int z){
while(x<=n){
int y1=y;
while(y1<=m){
dis[x][y1]+=z;
y1+=lowbit(y1);
}
x+=lowbit(x);
}
return;
}
int sum(int x,int y){
int ans=0;
while(x>0){
int y1=y;
while(y1>0){
ans+=dis[x][y1];
y1-=lowbit(y1);
}
x-=lowbit(x);
}
return ans;
}
int main(){
scanf("%d %d",&n,&m);
while(scanf("%d",&t)!=EOF){
if(t==1){
scanf("%d %d %d",&a,&b,&k);
add(a,b,k);
}
else if(t==2){
scanf("%d %d %d %d",&a,&b,&c,&d);
printf("%d\n",sum(c,d)-sum(a-1,d)-sum(c,b-1)+sum(a-1,b-1));
}
}
return 0;
}
- 然后就长这样:
- 最后一个点WA了,一想,没错,没开long long…没事,改一下
- 数据加强后,开long long会超时,(我以前就做过int改long long会WA掉的,貌似是大量运算时long long更长更耗时)
- 这个超时就很让人无奈,因为树状数组已经非常快,算法本身已是最优,这让人咋改?
- 于是,上网,找大神博客,but,这道题数据加强过,so,网上的代码集体超时
- 自己魔改了亿小下,终于AC了,(真·擦边过,999MS,还有谁!!!)
-代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long dis[5001][5001];
int a,b,c,d,t,k;
char ch;
int read(){
ch=getchar();
int x=0;
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x;
}
inline int lowbit(int x){
return x&(-x);
}
inline void add(int x,int y,int z){
while(x<=n){
int y1=y;
while(y1<=m){
dis[x][y1]+=z;
y1+=lowbit(y1);
}
x+=lowbit(x);
}
return;
}
inline long long sum(int x,int y){
long long ans=0;
while(x>0){
int y1=y;
while(y1>0){
ans+=dis[x][y1];
y1-=lowbit(y1);
}
x-=lowbit(x);
}
return ans;
}
int main(){
n=read();m=read();
while(scanf("%d",&t)!=EOF){
if(t==1){
a=read();b=read();
scanf("%d",&k);
add(a,b,k);
}
else if(t==2){
a=read();b=read();c=read();
scanf("%d",&d);
long long ans1=0;
int x=c,y=d;
while(x>0){
int y1=y;
while(y1>0){
ans1+=dis[x][y1];
y1-=lowbit(y1);
}
x-=lowbit(x);
}
long long ans2=0;
x=a-1,y=d;
while(x>0){
int y1=y;
while(y1>0){
ans2+=dis[x][y1];
y1-=lowbit(y1);
}
x-=lowbit(x);
}
long long ans3=0;
x=c,y=b-1;
while(x>0){
int y1=y;
while(y1>0){
ans3+=dis[x][y1];
y1-=lowbit(y1);
}
x-=lowbit(x);
}
long long ans4=0;
x=a-1,y=b-1;
while(x>0){
int y1=y;
while(y1>0){
ans4+=dis[x][y1];
y1-=lowbit(y1);
}
x-=lowbit(x);
}
long long ans=ans1-ans2-ans3+ans4;
printf("%lld\n",ans);
}
if(ch==EOF) break;
}
return 0;
}
- 当然,这是极端情况,我用大号分是酱紫的
- 总之,这道题由于测点11数据要用long long而变得十分恶心,但魔改一下就可以过了。
- ps.不过可以试着多交两遍