数星星
poj2352
#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
tree<pair<int,int> ,null_type,less<pair<int,int> >,rb_tree_tag,tree_order_statistics_node_update>tr;
typedef long long ll;
#define endl '\n'
const int N=15100;
vector<pair<int,int> >v(N);
int ans[N];
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n;
cin>>n;
for( int i=0;i<n;i++){
cin>>v[i].first>>v[i].second;
}
sort(v.begin(),v.begin()+n);
int idx=0;
for( int i=0;i<n;i++){
int level=tr.order_of_key(make_pair(v[i].second+1,0));
tr.insert(make_pair(v[i].second,++idx));
ans[level]++;
}
for( int i=0;i<n;i++){
cout<<ans[i]<<endl;
}
}
公路交叉数
poj3067
#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
#define endl '\n'
#define lowbit(x) x&(-x)
const int inf=0x3f3f3f3f;
const int K=10100;
int c[1010];
int query( int x){
int sum=0;
while(x>0){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update( int i){
while(i<=1000){
c[i]++;
i+=lowbit(i);
}
}
int solve(){
int n,m,k;
cin>>n>>m>>k;
vector<pair<int,int> >v(K);
for( int i=0;i<=1000;i++) c[i]=0;
for( int i=0;i<k;i++){
cin>>v[i].first>>v[i].second;
}
sort(v.begin(),v.begin()+k);
int res=0;
for( int i=0;i<k;i++){
res+=query(1000)-query(v[i].second);
update(v[i].second);
}
return res;
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t;
cin>>t;
for( int i=1;i<=t;i++){
printf("Test case %d: %d\n",i,solve());
}
}
子树查询
poj3321
首先进行dfs求解时间戳,然后使用时间戳将树上的结点编号映射到一个一维数组中,使用树状数组维护一维数组。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define lowbit(x) x&(-x)
const int N=100100;
const int M=N+N;
int h[N],ne[M],to[M];
int idx;
int cnt[N],sz[N];//时间戳
int c[N];
int have_apple[N];
int n,m;
void add( int a,int b){
to[idx]=b;ne[idx]=h[a];h[a]=idx++;
}
int idx2=0;
void dfs( int rt,int fa){
cnt[rt]=++idx2;
sz[rt]=1;
for( int i=h[rt];i!=-1;i=ne[i]){
int j=to[i];
if(j==fa) continue;
else{
dfs( j,rt);
sz[rt]+=sz[j];
}
}
}
int query( int x){
int sum=0;
while(x>0){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update( int i){
int val=0;
if(have_apple[i]==0) val=-1;
else val=1;
while(i<=n){
c[i]+=val;
i+=lowbit(i);
}
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n;
memset(h,-1,sizeof(h));
for( int i=1;i<=n;i++){
have_apple[i]=1;
update(i);
}
for( int i=1;i<n;i++){
int x,y;
cin>>x>>y;
add(x,y);add(y,x);
}
dfs(1,-1);
cin>>m;
for( int i=1;i<=m;i++){
string s;
int q;
cin>>s>>q;
if(s=="C"){
have_apple[cnt[q]]^=1;
update(cnt[q]);
}
else {
//cout<<cnt[q]+sz[q]+1<<" "<<cnt[q]-1<<endl;
cout<<query(cnt[q]+sz[q]-1)-query(cnt[q]-1)<<endl;
}
}
return 0;
}
矩形区间查询
poj1195
首先维护x,再维护y。
查询通过容斥原理进行查询。
发现模板有一个bug,update的下标不能从0开始,下标需要全部加一。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define lowbit(x) x&(-x)
const int N=1030;
int c[N][N];
int n;
int query( int x,int y){
int sum=0;
while(x>0){
int yy=y;
while(yy>0){
sum+=c[x][yy];
yy-=lowbit(yy);
}
x-=lowbit(x);
}
return sum;
}
void update( int x,int y,int val){
while(x<=n){
int yy=y;
while(yy<=n){
c[x][yy]+=val;
yy+=lowbit(yy);
}
x+=lowbit(x);
}
}
int main(){
// ios_base::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
cin>>n>>n;
while(1){
int q;
cin>>q;
if(q==1){
int x,y,val;
cin>>x>>y>>val;
++x,++y;
update(x,y,val);
}
else if(q==2){
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
++x1,++x2,++y1,++y2;
cout<<query(x2,y2)-query(x2,y1-1)-query(x1-1,y2)+query(x1-1,y1-1)<<endl;
}
else break;
}
return 0;
}