pku1916 Rat Attack 动态统计之经典好题

pku1916 Rat Attack 动态统计之经典好题

题意
pku1916 Rat Attack 动态统计之经典好题_第1张图片
在管道的焦点处有N个种群数目为Pi的鼠群,N<20000,现在要在某个焦点处放一个炸弹,炸弹效力范围是以炸弹为中点的2d*2d的矩形。问炸弹放在哪里可以炸死最多的老鼠,如果有重复则优先保证X坐标最小,如果还有重复就Y坐标最小。
解法
这种题目一般是采用X扫描线+平衡树/树状数组统计的方法。但是这题由于还有第二和第三优先级,我们必须扫描线移动一下就统计一下,不能等到扫描线距离达到2d再统计,然后小x坐标就是后扫描线坐标减去d。用平衡树/树状数组统计时也要注意这个问题。详细情况见代码(我依然很猥琐的用了STL MAP)
PS,好不容易一题在poj rank进前3,不容易啊。。

 1 # include  < cstdio >
 2 # include  < map >
 3 # include  < algorithm >
 4 using   namespace  std;
 5 struct  node
 6 {
 7    int x,y,num;
 8    bool operator<(const node &pos) const
 9    {
10        return x<pos.x;
11    }

12}
data[ 20005 ];
13 int  d,n;
14 map < int , int >  refer;
15 void  calbest( int  nx, int   & best, int   & x, int   & y)
16 {
17    map<int,int>::iterator s=refer.begin(),e=refer.begin();
18    int total=0,last=e->first;
19    while(e!=refer.end())
20    {
21        while(e!=refer.end()&&e->first<=s->first+2*d)
22        {
23            total+=e->second;
24            last=e->first;
25            e++;
26        }

27        if(total>best||total==best&&nx-d<x||total==best&&nx-d==x&&last-d<y)
28            best=total,x=nx-d,y=last-d;
29        total-=s->second;
30        s++;
31    }

32}

33 int  main()
34 {
35    //freopen("ans.txt","w",stdout);
36    int test;
37    scanf("%d",&test);
38    while(test--)
39    {
40        scanf("%d%d",&d,&n);
41        for(int i=0;i<n;i++)
42            scanf("%d%d%d",&data[i].x,&data[i].y,&data[i].num);
43        sort(data,data+n);
44        int s=0,e=0;
45        refer.clear();
46        int best=-1,y,x;
47        while(e<n)
48        {
49            int tmp;
50            while(true)
51            {
52                if(e>=n||data[e].x-data[s].x>2*d) break;
53                tmp=data[e].x;
54                while(e<n&&data[e].x==tmp) 
55                    {
56                        refer[data[e].y]+=data[e].num;
57                        e++;
58                    }

59                calbest(data[e-1].x,best,x,y);
60            }

61            tmp=data[s].x;
62            while(data[s].x==tmp&&s<n)
63            {
64                refer[data[s].y]-=data[s].num;
65                if(refer[data[s].y]==0) refer.erase(data[s].y);
66                s++;
67            }

68        }

69        printf("%d %d %d\n",x>=0?x:0,y>=0?y:0,best);
70        
71    }

72    return 0;
73}

74
75

你可能感兴趣的:(pku1916 Rat Attack 动态统计之经典好题)