poj 2464 Brownie Points II(扫描线)

题目链接:poj 2464 Brownie Points II

题意:

题意很迷啊。

有一些点,Stan选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画了条横线。
Stan选一,三象限的点,Ollie选二、四象限的点。
Stan的策略是,自己画一条竖线之后,Ollie有很多种选择,在所有选择中,Stan能获得数目的最小值的最大值,而Ollie的选择便 是让自己越多越好。
题解:
下面是cxlove dalao的题解:
首先对于某个方向离散化,我是按x排序,将y离散化。
建立两个树状数组,表示竖线左边的点个数,右边的点个数
然后按x递增扫描一遍,预先先把所有点插入到右树中。
然后逐步更新左树和右树。
 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define F(i,a,b) for(int i=a;i<=b;++i)
 6 using namespace std;
 7 
 8 const int N=2e5+7,inf=1e9;
 9 int n,hsh[N],h_ed,val[N],C1[N],C2[N],ret;
10 pair<int,int>a[N];
11 vector<int>ans;
12 
13 void add(int *C,int x,int v){while(x<=h_ed)C[x]+=v,x+=x&-x;}
14 int ask(int *C,int x){int an=0;while(x)an+=C[x],x-=x&-x;return an;}
15 
16 int main()
17 {
18     while(scanf("%d",&n),n)
19     {
20         ans.clear(),ret=-1;
21         F(i,1,n)
22         {
23             scanf("%d%d",&a[i].first,&a[i].second);
24             hsh[i]=a[i].second;
25         }
26         sort(hsh+1,hsh+1+n),h_ed=unique(hsh+1,hsh+1+n)-hsh-1;
27         F(i,1,n)a[i].second=lower_bound(hsh+1,hsh+1+h_ed,a[i].second)-hsh;
28         memset(C1,0,sizeof(C1)),memset(C2,0,sizeof(C2));
29         sort(a+1,a+1+n);
30         F(i,1,n)add(C2,a[i].second,1);
31         int st=1;
32         F(i,1,n)if(i==n||a[i+1].first!=a[i].first)
33         {
34             int aa=-1,bb=-1;
35             F(j,st,i)add(C2,a[j].second,-1);
36             F(j,st,i)
37             {
38                 int y=a[j].second;
39                 int ta=ask(C1,y-1)+ask(C2,h_ed)-ask(C2,y);
40                 int tb=ask(C1,h_ed)-ask(C1,y)+ask(C2,y-1);
41                 if(tb==bb)aa=min(aa,ta);
42                 else if(tb>bb)bb=tb,aa=ta;
43             }
44             if(aa>ret)ret=aa,ans.clear();
45             if(aa==ret)ans.push_back(bb);
46             F(j,st,i)add(C1,a[j].second,1);
47             st=i+1;
48         }
49         sort(ans.begin(),ans.end());
50         ans.erase(unique(ans.begin(),ans.end()),ans.end());
51         printf("Stan: %d; Ollie:",ret);
52         for(int i=0;i<ans.size();i++)
53             printf(" %d",ans[i]);
54         puts(";");
55     }
56     return 0;
57 }
View Code

 

posted @ 2017-08-23 20:56  bin_gege  阅读(137)  评论(0编辑  收藏  举报