4022 Bombing
题目大意:给你n个点(二位),坐标范围(<10^9)然后m次询问
0 s 表示询问x = s这条线上有多少个点
1 s 表示询问y = s这条线上有多少个点
一个点被算过以后和面的询问就不能再计算了
分析:最容易想到的就是每次询问后把计算过的点标记一下下次询问就不需要再计算了,然后对于维护一下每个横纵线上有多少点。但坐标范围很大怎么办?
STL!!!真的是太爽了,建两个map<int, multiset<int> >的map x,y表示 横纵有多少个点,每次询问是返回该值就可,然后把对应的另一维的该点删除掉就可以了。

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <set> 5 #include <map> 6 using namespace std; 7 typedef map<int ,multiset <int> > m; 8 m x,y; 9 int getans(m &x,m &y,int pos) 10 { 11 int ans = x[pos].size(); 12 for(multiset<int> ::iterator i = x[pos].begin();i!=x[pos].end();++i) 13 y[*i].erase(pos); 14 x[pos].clear(); 15 return ans; 16 } 17 int main () 18 { 19 int n,m; 20 while(scanf("%d%d",&n,&m)!=EOF) 21 { 22 if(n==0&&m==0)break; 23 x.clear();y.clear(); 24 for(int i=0;i<n;++i) 25 { 26 int xx,yy; 27 scanf("%d%d",&xx,&yy); 28 x[xx].insert(yy); 29 y[yy].insert(xx); 30 } 31 for(int i=0;i<m;++i) 32 { 33 int cmd,pos; 34 scanf("%d%d",&cmd,&pos); 35 if(cmd==0)printf("%d ",getans(x,y,pos)); 36 else printf("%d ",getans(y,x,pos)); 37 } 38 printf(" "); 39 } 40 }