源自------------------------------------------------Ice_Crazy
树状数组水题果题模板题:hdu3792、hdu1541、hdu4046、hdu2689
hdu2838
树状数组求逆序数果题。
hdu2433
树状数组求顺序数,不错的题。
sum[i~j]=val[i]+val[i+1]+...+val[j]-(j-i+1)*a;-------------(1)
sum[i~j]=sum[j]-sum[i-1];----------------------------------(2)
所以(1)>0等效于(2)>0。
所以对读入的序列转化后求顺序数的对数既可。
蛋疼的是hdu又一道必须用__int64的题,long long送掉一血。。
hdu4312
关键是坐标系的转换:
“对于原坐标系中两点间的 Chebyshev 距离,是将坐标轴顺时针旋转45度并将
所有点的坐标值放大sqrt(2)倍所得到的新坐标系中的Manhattan距离的二分之
一。”。。既:(x,y)→(x-y,x+y),求出来的结果/2。
hdu1559
树状数组水题。
10秒的时间,二维树状数组(或线段树)应该也能过,不过感觉用1维的配合
着递推关系会快那么一点儿。
下面是1维的树状数组(横向、纵向分别建立了一个,C[0]是横向的、C[1]
是纵向的)的代码。
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define N 1011
int n,m,C[2][N][N];
int lowbit[N];
int X,Y;
int map[N][N];
void get_lowbit()
{
int i;
for(i=1;i<=1000;i++) lowbit[i]=i&(-i);
}
int sum(int K,int x,int k)
{
int p=0;
while(0<k)
{
p+=C[K][x][k];
k-=lowbit[k];
}
return p;
}
void update(int K,int x,int k,int dir,int limit)
{
while(0<k && k<=limit)
{
C[K][x][k]+=dir;
k+=lowbit[k];
}
}
void get_C()
{
int i,l;
memset(C,0,sizeof(C));
for(i=1;i<=n;i++)
for(l=1;l<=m;l++)
update(0,i,l,map[i][l],m);
for(i=1;i<=m;i++)
for(l=1;l<=n;l++)
update(1,i,l,map[l][i],n);
}
int get_ans()
{
int ans;
int i,l;
int temp,pre;
ans=pre=0;
for(i=1;i<=X-1;i++) pre+=sum(0,i,Y-1);
for(i=X;i<=n;i++)
{
temp=pre-sum(0,i-X,Y-1)+sum(0,i,Y-1);
pre=temp;
for(l=Y;l<=m;l++)
{
temp=temp-(sum(1,l-Y,i)-sum(1,l-Y,i-X))+(sum(1,l,i)-sum(1,l,i-X));
if(temp>ans) ans=temp;
}
}
return ans;
}
int main()
{
int T;
int i,l;
get_lowbit();
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&n,&m,&X,&Y);
for(i=1;i<=n;i++)
for(l=1;l<=m;l++)
scanf("%d",&map[i][l]);
get_C();
printf("%d\n",get_ans());
}
return 0;
}
hdu2852
树状数组+二分。
由于是容器,所以值为x的元素可以同时存在n多个(这个可以理解)。而删除,每次删除只删除
其中一个。。。表示无法理解,题意不清,弄得我最后无奈的看了别人的代码才检查出来,囧~~
另外,就按照题目的“Elment”拼吧,如果感兴趣了你可以试下拼“Element”能不能ac。。。
hdu1892
二维树状数组模板题。
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
int C[1011][1011];
int map[1011][1011];
int lowbit[1011];
int sum(int x,int y)
{
int p=0;
int temp=y;
while(x>0)
{
y=temp;
while(y>0)
{
p+=C[x][y];
y-=lowbit[y];
}
x-=lowbit[x];
}
return p;
}
void update(int x,int y,int dir)
{
int temp=y;
while(x>0 && x<=1001)
{
y=temp;
while(y>0 && y<=1001)
{
C[x][y]+=dir;
y+=lowbit[y];
}
x+=lowbit[x];
}
}
int main()
{
int T,Case;
int q;
int i,l;
char str[11];
int x1,y1,x2,y2,z;
int temp;
int x_top,y_top,x_bot,y_bot;
int a,b,c,d;
scanf("%d",&T);
for(Case=1;Case<=T;Case++)
{
scanf("%d",&q);
memset(C,0,sizeof(C));
for(i=1;i<=1001;i++) lowbit[i]=i&(-i);
for(i=1;i<=1001;i++)
for(l=1;l<=1001;l++)
{
map[i][l]=1;
update(i,l,1);
}
printf("Case %d:\n",Case);
while(q--)
{
scanf("%s",str);
if(str[0]=='A')
{
scanf("%d%d%d",&x1,&y1,&z);
x1++;y1++;
update(x1,y1,z);
map[x1][y1]+=z;
}
else if(str[0]=='D')
{
scanf("%d%d%d",&x1,&y1,&z);
x1++;y1++;
temp=map[x1][y1]>z?z:map[x1][y1];
update(x1,y1,-temp);
map[x1][y1]-=temp;
}
else if(str[0]=='M')
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&z);
x1++;y1++;x2++;y2++;
temp=map[x1][y1]>z?z:map[x1][y1];
map[x1][y1]-=temp;
map[x2][y2]+=temp;
update(x1,y1,-temp);
update(x2,y2,temp);
}
else if(str[0]=='S')
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1++;y1++;x2++;y2++;
x_top=x1>x2?x1:x2;
y_top=y1>y2?y1:y2;
x_bot=x1>x2?x2:x1;
y_bot=y1>y2?y2:y1;
a=sum(x_top,y_top);
b=sum(x_bot-1,y_bot-1);
c=sum(x_bot-1,y_top);
d=sum(x_top,y_bot-1);
printf("%d\n",a-c-d+b);
}
}
}
return 0;
}
hdu2642
二维树状数组水题。
hdu4311
树状数组+二分(可以不用二分),当时废话的太多,我就不搬过来了, 传送~。。。
hdu2836
(树状数组(或线段树)&&二分)&&DP,废话也比较多, 传送。。。。