【枚举优化】轰炸

来源:互联网 发布:怎样推广淘宝店名 编辑:程序博客网 时间:2024/04/20 08:29

1.轰炸(bomb.pas/c/cpp)

【题目描述】

平面上有n个目标,你驾驶着一辆轰炸机要轰炸这些目标,由于技术限制,每次轰炸的目标必须在一条直线上,请你写个程序统计每次能摧毁多少个目标。

注意,目标不能重复计数,也就是此次轰炸后目标下次就消失了。

【输入格式】

第一行两个数nm,代表目标个数和轰炸的次数

下面n行,每行两个整数(xy),代表每个目标的坐标

再下面m行,第一个数为010表示此次轰炸是一条水平的直线,1则表示竖直

第二个数t表示此直线的位置(x = t或者y = t

【输出格式】

m行,表示每次轰炸的目标数

【样例输入】

3 2

1 2

1 3

2 3

0 1

1 3

【样例输出】

2

1

 

【数据规模】

30%  nm<=5000

100% n,m <= 100000

|x|, |y| <= 10^9

【时间限制】

1s

 

 

这道题的标准解法就是朴素模拟。可笑的是只有我和laury做出来了。所以想多了的孩纸可以自己抽自己。

优化在于二分出下界,再往后枚举(本来更好的方法是用类似于前向星的解决办法维护first,但是考虑到空间无法承受,于是折中使用这种办法)

我继续优化了一点,效果不明显。使用dancing links,将炸毁的都删除掉,减少了枚举量。同时由于dancing links的优势,不会修改原来点的信息,所以如果二分下界的时候找到了已经删除掉的点,再往后枚举,最终也会枚举到正确的地方。

 

 

#include <cstdio>#include <bitset>#include <algorithm>using std::sort;using std::lower_bound;using std::upper_bound;bool used[100010];struct P1{long x;long i;bool operator<(const P1& p12)const{return x<p12.x;}bool operator<(const long p12)const{return x<p12;}};struct P2{long y;long i;bool operator<(const P2& p22)const{return y<p22.y;}bool operator<(const long p22)const{return y<p22;}};P1 p1[100010];P2 p2[100010];long nxt1[100010];long nxt2[100010];long pre1[100010];long pre2[100010];long getint(){long rs=0;bool sgn=1;char tmp;do tmp = getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp=='-'){sgn=0;tmp=getchar();}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}int main(){freopen("bomb.in","r",stdin);freopen("bomb.out","w",stdout);long n = getint();long m = getint();for (long i=1;i<n+1;i++){p1[i].x=getint();p2[i].y=getint();p1[i].i = p2[i].i = i;}sort(p1+1,p1+1+n);sort(p2+1,p2+1+n);for (long i=1;i<n+1;i++){nxt1[i] = i+1;pre1[i] = i-1;nxt2[i] = i+1;pre2[i] = i-1;}nxt1[n] = 1;nxt2[n] = 1;pre1[1] = n;pre2[1] = n;for (long i=1;i<m+1;i++){long a = 0;do a = getchar()-'0';while (a!=0&&a!=1);long b = getint();if (a == 0){long c = 0;long f = lower_bound(p1+1,p1+n+1,b)-p1;for (long j=f;j<n+1;j++){if (p1[j].x != b) break;if (!used[p1[j].i]){used[p1[j].i] = true;nxt1[pre1[p1[j].i]] = nxt1[p1[j].i];pre1[nxt1[p1[j].i]] = pre1[p1[j].i];c ++;}}printf("%ld\n",c);}else{long c = 0;long f = lower_bound(p2+1,p2+n+1,b)-p2;for (long j=f;j<n+1;j++){if (p2[j].y != b) break;if (!used[p2[j].i]){used[p2[j].i] = true;nxt2[pre2[p2[j].i]] = nxt2[p2[j].i];pre2[nxt2[p2[j].i]] = pre2[p2[j].i];c ++;}}printf("%ld\n",c);}}return 0;}