去年学树状数组的时候用树状数组写过这题,如今学线段树,用线代树写了一次,发现线段树的代码好像更长,程序运行时间也比树状数组久
现在树状数组也忘光光了,,, (┬_┬)。。。
PS: 某渣看到以前的代码 真的是不舒服啊 吐槽一下自己
今天写的线段树:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<limits.h>
using namespace std;
#define MAXN 50001
struct node
{
int l,r;
int sum;
}a[4*MAXN];
void Build(int l,int r,int n)// 构建线段树
{
a[n].l= l;
a[n].r= r;
a[n].sum= 0;
if(l == r)
return;
int mid= (l + r) /2;
Build(l, mid, 2*n);
Build(mid + 1, r, 1+2*n);
}
void Add(int num,int v, int n)
{
if(v == a[n].l && v == a[n].r)
{
a[n].sum += num;
return;
}
int mid= (a[n].l + a[n].r)/ 2;
if(v<= mid)
Add(num, v, 2*n);
else
Add(num,v,1+ 2*n);
a[n].sum= a[2*n].sum + a[2*n+1].sum;
}
void Sub(int num, int v, int n)
{
if(v == a[n].l && v == a[n].r)
{
a[n].sum-= num;
return;
}
int mid= (a[n].l +a[n].r)/ 2;
if(v<= mid)
Sub(num, v, 2*n);
else
Sub(num,v,1+ 2*n);
a[n].sum= a[2*n].sum + a[2*n+1].sum;
}
int Query(int l,int r, int n)
{
if(l == a[n].l && r == a[n].r)
return a[n].sum;
int mid= ( a[n].l + a[n].r) /2;
if(r<= mid)
return Query(l, r, 2*n);
else if(l> mid)
return Query(l, r, 1+ 2*n);
else
return Query(l, mid, 2*n) + Query(mid + 1, r, 1+ 2*n);
}
int main()
{
int T;
scanf("%d",&T);
for(int t= 1; t<= T; t++)
{
int n;
scanf("%d",&n);
Build(1,n,1);
int xixi;
for(int i= 1; i<= n; i++)
{
scanf("%d",&xixi);
Add(xixi,i,1);
}
char ch[10];
int p,q;
printf("Case %d:\n",t);
while(scanf("%s",&ch)!=EOF)
{
if(ch[0]=='E')
break;
scanf("%d%d",&p,&q);
if(ch[0]=='A')
Add(q, p, 1);
else if(ch[0]=='S')
Sub(q, p, 1);
else
{
int sum= Query(p, q, 1);
printf("%d\n",sum);
}
}
}
return 0;
}
以前写的恶心树状数组:
#include<stdio.h>
#include<math.h>
#include<string.h>
int c[50010]={0};
int lowbit(int i)
{
return i&(-i);
}
void add(int x,int delta,int n)
{
for(int i=x; i<= n;i+=lowbit(i))
c[i]+=delta;
}
int Getsum(int x)
{
int sum=0;
for(int i=x; i> 0;i-=lowbit(i) )
sum+=c[i];
return sum;
}
int main()
{
int m,n,k;
scanf("%d",&m);
for(k= 1;k<= m; k++)
{memset(c,0,sizeof(c));
int a;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a);
add(i,a,n);
}
char s[10];
getchar();
int flog=0;
while(scanf("%s",&s)!=EOF)
{int x=0,y=0,sum;
if(s[0]=='E')
break;
scanf("%d%d",&x,&y);
if(s[0]=='A')
add(x,y,n);
else if(s[0]=='S')
add(x,-y,n);
else if(s[0]=='Q')
{
if(flog==0)
{printf("Case %d:\n",k);flog++;}
sum=Getsum(y) - Getsum(x-1);
printf("%d\n",sum);}
}
}
return 0;
}