vijos 1066 弱弱的战壕

#include<bits/stdc++.h>
using namespace std;
const int N=15005;
int tree[32010];//树状数组
int ans[N];//答案
int lowbit(int k){ //找到对应低一级数段 求lowbit的值 lowbit:二进制数k最低位1的十进制,计算c[t]展开的项数
return k & -k;
}
int sum(int k){ //查询区间和
int ans = 0;
while(k){
ans += tree[k];
k -= lowbit(k);
}
return ans;
}
void add(int k){ //给第x个数字+k
while(k < 32003){
tree[k] ++;
k += lowbit(k);
}
}
struct node {
int x,y;
} nos[N];
bool cmp(node a,node b) {
return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x);
}
int main() {
int n; cin>>n;
for(int i = 1; i <= n; i ++) cin >> nos[i].x >> nos[i].y;
sort(nos + 1, nos + n + 1, cmp);//从小到大排序位置
tree[1] = 0;
for(int i = 1; i <= n; i ++){ //计算答案
ans[sum(nos[i].y)] ++; //把i,y点之前的点的个数 都放进答案数组中
add(nos[i].y); //将这个点之前的 标记 加起来
}
for(int i = 0; i < n; i ++) cout << ans[i] << endl;
return 0;
}
本文介绍了一种使用树状数组(segment tree)算法解决小范围内区间和查询的问题,通过计算每个点前的累计点数,并动态维护区间和,以求解给定位置的点集中前点的数量。适用于处理位置与计数相关的问题,如图中小范围统计应用。
2365

被折叠的 条评论
为什么被折叠?



