我写的是二维线段树,理论时间复杂度是 O(nlog2n) ,看起来好像可行,但是不知道为什么就tle 63分了
愿意看的话代码在这里
#include <iostream>
using namespace std;
const int p=2048*2048*8+5;
template <class type>
class segment_tree
{
//在运行时确定具体范围
template <class node_type>
struct node
{
node_type sum;
node_type lazy;
};
node<type> t[p];
int n,m;
type build(int id,int lx,int ly,int rx,int ry,type *a[])
{
if(lx==rx&&ly==ry)
return t[id].sum=a[lx][ly];
int midx=(lx+rx)/2,midy=(ly+ry)/2;
return t[id].sum=build(id*4-2,lx,ly,midx,midy,a)+build(id*4-1,lx,midy+1,midx,ry,a)+build(id*4,midx+1,ly,rx,midy,a)+build(id*4+1,midx+1,midy+1,rx,ry,a);
}
inline void pushdown(int id,int lx,int ly,int rx,int ry)
{
if(lx!=rx||ly!=ry)
{
t[id*4-2].lazy+=t[id].lazy;
t[id*4-1].lazy+=t[id].lazy;
t[id*4 ].lazy+=t[id].lazy;
t[id*4+1].lazy+=t[id].lazy;
}
t[id].sum+=t[id].lazy*(rx-lx+1)*(ry-ly+1);
t[id].lazy=0;
}
inline bool in(int lx,int ly,int rx,int ry,int x,int y)
{
return lx<=x&&ly<=y&&x<=rx&&y<=ry;
}
inline int max(int x,int y)
{
return x>y?x:y;
}
inline int min(int x,int y)
{
return x<y?x:y;
}
void change(int id,int lx,int ly,int rx,int ry,int ux,int uy,int vx,int vy,type delta)
{
if(lx==ux&&ly==uy&&rx==vx&&ry==vy)
{
t[id].lazy+=delta;
return;
}
t[id].sum+=(rx-lx+1)*(ry-ly+1)*delta;
int mx=(ux+vx)/2,my=(uy+vy)/2;
bool f1=in(ux,uy,mx,my,lx,ly),
f2=in(ux,my+1,mx,vy,lx,ry),
f3=in(mx+1,uy,vx,my,rx,ly),
f4=in(mx+1,my+1,vx,vy,rx,ry);
if(f1)
change(id*4-2,lx,ly,min(rx,mx),min(ry,my),ux,uy,mx,my,delta);
if(f2)
change(id*4-1,lx,max(ly,my+1),min(rx,mx),ry,ux,my+1,mx,vy,delta);
if(f3)
change(id*4+0,max(lx,mx+1),ly,rx,min(ry,my),mx+1,uy,vx,my,delta);
if(f4)
change(id*4+1,max(lx,mx+1),max(ly,my+1),rx,ry,mx+1,my+1,vx,vy,delta);
}
type request(int id,int lx,int ly,int rx,int ry,int ux,int uy,int vx,int vy)
{
pushdown(id,ux,uy,vx,vy);
if(lx==ux&&ly==uy&&rx==vx&&ry==vy)
return t[id].sum;
int mx=(ux+vx)/2,my=(uy+vy)/2;
bool f1=in(ux,uy,mx,my,lx,ly),
f2=in(ux,my+1,mx,vy,lx,ry),
f3=in(mx+1,uy,vx,my,rx,ly),
f4=in(mx+1,my+1,vx,vy,rx,ry);
type ans=0;
if(f1)
ans+=request(id*4-2,lx,ly,min(rx,mx),min(ry,my),ux,uy,mx,my);
if(f2)
ans+=request(id*4-1,lx,max(ly,my+1),min(rx,mx),ry,ux,my+1,mx,vy);
if(f3)
ans+=request(id*4+0,max(lx,mx+1),ly,rx,min(ry,my),mx+1,uy,vx,my);
if(f4)
ans+=request(id*4+1,max(lx,mx+1),max(ly,my+1),rx,ry,mx+1,my+1,vx,vy);
return ans;
}
public:
void build(int x,int y)
{
n=x,m=y;
}
void build(int sizex,int sizey,type *a[])
{
n=sizex,m=sizey;
build(1,1,1,n,m,a);
}
void change(int lx,int ly,int rx,int ry,type delta)
{
change(1,lx,ly,rx,ry,1,1,n,m,delta);
}
type request(int lx,int ly,int rx,int ry)
{
return request(1,lx,ly,rx,ry,1,1,n,m);
}
};
segment_tree<int> t;
/*
class duipai
{
int a[1005][1005];
public:
void change(int lx,int ly,int rx,int ry,int delta)
{
for(int x=lx;x<=rx;x++)
for(int y=ly;y<=ry;y++)
a[x][y]+=delta;
}
int request(int lx,int ly,int rx,int ry)
{
int ans=0;
for(int i=lx;i<=rx;i++)
for(int j=ly;j<=ry;j++)
ans+=a[i][j];
return ans;
}
};
duipai g;
*/
int main()
{
char op='X';
int n,m;
cin>>op>>n>>m;
t.build(n,m);
while(cin>>op)
{
if(op=='L')
{
int lx,ly,rx,ry,delta;
cin>>lx>>ly>>rx>>ry>>delta;
t.change(lx,ly,rx,ry,delta);
}
else if(op=='k')
{
int lx,ly,rx,ry;
cin>>lx>>ly>>rx>>ry;
cout<<t.request(lx,ly,rx,ry)<<"\n";
}
}
return 0;
}