poj 2464 Brownie Points II(两棵线段树——线段树区间和)
来源:互联网 发布:一体智能马桶 知乎 编辑:程序博客网 时间:2024/04/30 00:06
Description
Those lines divide the plane into four quadrants. The quadrant containing points with arbitrarily large positive coordinates is the top-right quadrant.
The players score according to the number of brownie points in the quadrants. If a brownie point is crossed by a line, it doesn't count. Stan gets a point for each (uncrossed) brownie point in the top-right and bottom-left quadrants. Ollie gets a point for each (uncrossed) brownie point in the top-left and bottom-right quadrants.
Stan and Ollie each try to maximize his own score. When Stan plays, he considers the responses, and chooses a line which maximizes his smallest-possible score.
Input
Output
Sample Input
113 23 33 43 62 -21 -30 0-3 -3-3 -2-3 -43 -70
Sample Output
Stan: 7; Ollie: 2 3;
Source
题目:http://poj.org/problem?id=2464
题意:这题的题意实在是虐暴我们这种E文差的菜鸟了,题意理解对就花了一晚上的,有木有= =
就是两个人在玩一个游戏,平面上有n个点,stan要选一个点然后画一条穿过这个点的竖线,而ollie要选择一个被竖线穿过的点,画一条横线,然后平面就被分为4个象限,1,3象限的点数为stan的分数,2,4象限的点数为ollie的分数,在坐标轴上的点分数不算,现在stan想知道他一定能取得的最大得分,也就是选一条竖线,在最坏情况下得到的分数最大,而ollie则在stan选择竖线后尽量取最大,当然,stan可能有多种选法,所以ollie也就有多个得分。。。
分析:这题看清题意之后,其实方法蛮好想的,不过实现起来实在是麻烦,我的方法貌似跟别人的不大一样,不过也是大同小异,首先把y坐标离散化,然后统计大于每个y坐标的点数和小于它的点数,假设一开始stan选择x最小的竖线,那么很明显,ollie选择每个横线后两人的分数都可以统计出来(虽然有些横线选不到),只要构建两棵线段树,一棵统计stan的分数,另一棵统计ollie的分数,stan的线段树初始值就是大一y坐标的初始值,而ollie恰好相反,然后按x坐标,从小到大扫描所有点,对于一个点,先在包括它的线段上减1,然后询问,然后再在新的包括它的线段上加1,对于x坐标相同的点,要集体操作,因为这条竖线是一样的
描述不是很好,详细见代码吧= =
注意点:ollie的得分相同的就输出一次,坐标轴上的点不算,统计时候注意边界赋值
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define ls rt<<1#define rs rt<<1|1#define lson l,m,ls#define rson m+1,r,rsusing namespace std;const int mm=222222;const int mn=mm<<2;struct point{ int x,y;}g[mm];int dly[mn][2];int y[mm],a[mm],b[mm],q[mm];void pushdown(int rt,int o){ if(dly[rt][o]) { dly[ls][o]+=dly[rt][o]; dly[rs][o]+=dly[rt][o]; dly[rt][o]=0; }}void build(int l,int r,int rt){ dly[rt][0]=dly[rt][1]=0; if(l==r) { dly[rt][0]=b[l],dly[rt][1]=a[l]; return; } int m=(l+r)>>1; build(lson); build(rson);}void updata(int L,int R,int val,int l,int r,int rt,int o){ if(L<=y[l]&&R>=y[r]) { dly[rt][o]+=val; return; } pushdown(rt,o); int m=(l+r)>>1; if(L<=y[m])updata(L,R,val,lson,o); if(R>=y[m+1])updata(L,R,val,rson,o);}int query(int x,int l,int r,int rt){ if(l==r)return rt; pushdown(rt,0); pushdown(rt,1); int m=(l+r)>>1; if(x<=y[m])return query(x,lson); return query(x,rson);}bool cmp(point a,point b){ return a.x<b.x;}int main(){ int i,j,k,l,r,n,m,ans,maxx,minn; while(scanf("%d",&n),n) { for(i=0;i<n;++i) { scanf("%d%d",&g[i].x,&g[i].y); y[i]=g[i].y; } sort(y,y+n); sort(g,g+n,cmp); a[0]=0; for(m=i=0;i<n;++i) if(y[m]<y[i]) { b[m]=n-i; y[++m]=y[i]; a[m]=i; } b[m]=0;//初值边界没赋好导致wa了好几次 build(0,m,1); ans=r=i=0; while(i<n) { for(j=i;j<n;++j)//x坐标相同的要集体操作 { if(g[j].y>y[0])updata(y[0],g[j].y-1,-1,0,m,1,0); if(g[j].y<y[m])updata(g[j].y+1,y[m],-1,0,m,1,1); if(g[j].x!=g[j+1].x)break; } maxx=0,minn=n; for(k=i;k<=j;++k) { l=query(g[k].y,0,m,1); minn=min(minn,dly[l][0]); maxx=max(maxx,dly[l][1]); } if(minn==ans)q[r++]=maxx; if(minn>ans) { ans=minn; q[0]=maxx; r=1; } for(;i<=j;++i) { if(g[i].y>y[0])updata(y[0],g[i].y-1,1,0,m,1,1); if(g[i].y<y[m])updata(g[i].y+1,y[m],1,0,m,1,0); } } sort(q,q+r); for(k=i=0;i<r;++i)//相同分数就输出1次 if(q[k]<q[i])q[++k]=q[i]; printf("Stan: %d; Ollie:",ans); for(i=0;i<=k;++i)printf(" %d",q[i]); puts(";"); } return 0;}
- poj 2464 Brownie Points II(两棵线段树——线段树区间和)
- Brownie Points II - POJ 2464 线段树
- POJ 2464 Brownie Points II 树状数组||线段树
- 线段树专题:poj 2464 Brownie Points II
- POJ 2464 Brownie Points II(树状数组||线段树)
- POJ 2464 Brownie Points II(线段树:扫描线)
- POJ_2464 Brownie Points II 线段树
- UVA10869 - Brownie Points II(线段树)
- poj 2464 Brownie Points II
- POJ 2464 Brownie Points II --树状数组
- poj 2464 Brownie Points II 树状数组
- hdoj1156_rownie Points II(线段树)
- Points in Segments (II)(线段树)
- poj 2464 Brownie Points II (扫描线)
- POJ 2464 Brownie Points II(树状数组+扫描线)
- POJ 2464 Brownie Points II(树状数组)
- Poj 2464 Brownie Points II(平面两条垂直的先划分成四个象限,一三象限和二四象限各有多少个)
- POJ 3468 线段树区间
- 解决几百万条以上数据分页让人蛋疼的 SQL2005, SQL2008最后一页卡死,最后一页查询超时的源码
- Android应用不完全退出问题
- 在多层架构中datareader传递的问题
- Linux内存管理图解
- 读取APK中versionCode信息
- poj 2464 Brownie Points II(两棵线段树——线段树区间和)
- 装饰设计模式
- Log4j输出日志教程
- SQL Server 中 RAISERROR 的用法
- Objective-C中获取类名
- 错误的策略最可怕
- sharepoint 2007 版本6421和6554 security Auditing Reports log 中的差别,及权限变更的具体位置查询
- C# SharpPcap编程注意事项
- Function实现ALV Table五:布局功能