不懂树状数组时什么意思,找了个简单的树状数组做!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; #define N 32001 int sum[N+1]; //算这个^k有一个快捷的办法,定义一个函数如下即可 //利用机器补码的特点,这个函数可以改得更方便 int lowbit(int k) { return k&(-k); } //如果要把a[i]增加v,可以通过调用如下函数实现 void add(int i,int v) { while(i<=N) { sum[i]+=v; cout<<"i:"<<i<<" >>"<<sum[i]<<endl; i+=lowbit(i); } } //如果要统计a[1]到a[i]之间的和,可以通过调用如下函数实现 int getSum(int i) { int s=0; while(i>0) { s+=sum[i]; cout<<"--i:"<<i<<" --"<<s<<endl; i-=lowbit(i); } return s; } int main() { int n,i,x,y; cin>>n; int*result=new int[n]; //初始化数组 for(i=0; i<n; i++) { result[i]=0; } for(i=1; i<=N; i++) { sum[i]=0; } for(i=0; i<n; i++) { cin>>x>>y; int t=getSum(x+1); result[t]++;//统计 cout<<t<<" "<<result[t]<<endl; add((x+1),1);//更新sum[i]的值 } for(i=0; i<n; i++) { cout<<result[i]<<endl; } return 1; }
只要有方法,也可以不用上面的方法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<stdio.h> using namespace std; struct node{ int aa,bb,flag,left,right; }; node b[100000]; int a[50000][3],f[50000],c[50000],tot; void build(int x,int y) { int now; tot++; now=tot; b[now].aa=x; b[now].bb=y; b[now].flag=0; if (x!=y) { b[now].left=tot+1; build(x,(x+y)/2); b[now].right=tot+1; build((x+y)/2+1,y); } } void insert(int x,int y) { int mid; if ((b[x].aa==b[x].bb)&&(b[x].aa==y)) { b[x].flag++; } else { mid=(b[x].aa+b[x].bb)/2; if (y<=mid) insert(b[x].left,y); if (y>mid) insert(b[x].right,y); b[x].flag=b[b[x].left].flag+b[b[x].right].flag; } } void find(int x,int y,int z) { int mid; if (b[x].aa==b[x].bb) c[z]+=b[x].flag; else { mid=(b[x].aa+b[x].bb)/2; if (y<=mid) find(b[x].left,y,z); if (y>mid) {c[z]+=b[b[x].left].flag;find(b[x].right,y,z);} } } int main() { int n,max,i; scanf("%d",&n); max=0; for(i=1;i<=n;i++) { scanf("%d%d",&a[i][0],&a[i][1]); if (a[i][0]>max) max=a[i][0]; } tot=0; build(0,max); for(i=1;i<=n;i++) { c[i]=0; find(1,a[i][0],i); insert(1,a[i][0]); } for(i=0;i<=n;i++) f[i]=0; for(i=1;i<=n;i++) f[c[i]]++; for(i=0;i<=n-1;i++) printf("%d\n",f[i]); return 0; }
【树状数组】数星星(POJ2352 star)
Time Limit:1000MS Memory Limit:65536K
Total Submit:23 Accepted:16
Description
天文学家经常观察星象图。星象图中用平面上的点来表示一颗星星,每一颗星星都有一个笛卡尔坐标。设定星星的等级为其左下角星星的总数。天文学家们想知道星星等级的分布情况。
比如上图,5号星星的等级为3(其左下角有编号为1、2、4的星星共三颗)。2号星星和4号星星的等级为1。在上图中只
有一颗星星等级为0,两颗星星等级为1,一颗星星等级为2,一颗星星等级为3。
给定一个星象图,请你写一个程序计算各个等级的星星数目。
Input
输入的第一行包含星星的总数N (1<=N<=15000)。接下来N行,描述星星的坐标(X,Y)(X和Y用空格分开,
0<=X,Y<=32000)。星象图中的每个点处最多只有一颗星星。所有星星按Y坐标升序排列。Y坐标相等的星星按X坐标升序排列。
Output
输出包含N行,每行一个整数。第一行包含等级0的星星数目,第二行包含等级1的星星数目,依此类推,最后一行包含
等级为N-1的星星数目。
Sample Input
5
1 1
5 1
7 1
3 3
5 5
Sample Output
1
2
1
1
0