poj2464Brownie Points II(树状数组)

2024-05-02 23:48

本文主要是介绍poj2464Brownie Points II(树状数组),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

晚上写了好久,终于把奇丑无比的代码改好了,试了几个样例都没问题,然后1A,真舒服

题目大意就是坐标平面上给N个点,然后先是Stan经过一个点做一条竖线,随之Ollie在Stan所做竖线上所有的点中选一个点做一条横线,两条线将平面分为四块,

Stan的得分是右上和左下两块中点数之和,Ollie得分是左上和右下两块中点数之和,在直线上的点统统不计

最关键的是:两个人都想让自己的得分尽量高,然后输出Stan至少能得多少分(是是是Stan是绝顶聪明的一定不会放水选次优解的),且输出Ollie在每一种Stan

取到Stan的最优解时Ollie能拿多少分

首先N只有200000,第一想法就是暴力枚举两条线的交点,这样只要能快速求出对应四个块有多少个点就OK了

这个时候我想着看能不能降一维,因为开不下二维树状数组,降维首先想到将某一关键字排序,但好像都不能成功降维,不过隐约可以感觉到要以x为关键字排序

然后想想维护y轴可以用树状数组,在暴力扫的时候用两个树状数组,一个维护现在还没有扫到的点(那么这些点的x值肯定大于当前点的x值),所以在这个树状

数组里可以查询右上和右下的点,另一个树状数组用于维护扫过的点,那么这些点的x值肯定小于当前点的x值,所以这个树状数组里可以查询左上和左下的点

不过注意x值相同的点之间的处理,而且y是要离散化一下的

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=200005;
int N;
struct BIT{int t[maxn];void init(){memset(t,0,sizeof t);}void update(int x,int v){while(x<maxn){t[x]+=v;x+=(x&-x);}}long long query(int x){int ans=0;while(x){ans+=t[x];x-=(x&-x);}return ans;}
}thl,thr;
struct node
{int x,y,id;
}num[maxn];
bool cmp(node a,node b)
{return a.x<b.x;
}
bool CMP(node a,node b)
{return a.y<b.y;
}
int st[maxn];
int main()
{while(~scanf("%d",&N)&&N){int res=-1;int tot=0;thl.init(),thr.init();for(int i=0;i<N;i++)scanf("%d%d",&num[i].x,&num[i].y);sort(num,num+N,CMP);num[0].id=1;for(int i=1;i<N;i++)if(num[i].y==num[i-1].y)num[i].id=num[i-1].id;else num[i].id=num[i-1].id+1;for(int i=0;i<N;i++)thr.update(num[i].id,1);sort(num,num+N,cmp);int i=0;while(i<N){int tempanss=10000000;int temp=i;while(num[temp].x==num[temp+1].x){temp++;thr.update(num[temp].id,-1);}for(int j=i;j<=temp;j++){int ans=thl.query(num[j].id-1)+thr.query(200001)-thr.query(num[j].id);tempanss=min(ans,tempanss);}if(temp>i)thr.update(num[i].id,-1);int ti=i;while(ti<=temp){if(tempanss>maxn){int ans=thl.query(num[ti].id-1)+thr.query(200001)-thr.query(num[ti].id);tempanss=min(tempanss,ans);}if(tempanss>res&&tempanss<maxn){tot=0;int ans=thl.query(200005)-thl.query(num[ti].id)+thr.query(num[ti].id-1);st[tot++]=ans;res=tempanss;}else if(tempanss==res&&tempanss<maxn){int ans=thl.query(200005)-thl.query(num[ti].id)+thr.query(num[ti].id-1);st[tot++]=ans;}ti++;}if(temp==i)thr.update(num[i].id,-1);while(i<=temp){thl.update(num[i].id,1);i++;}}sort(st,st+tot);int a=unique(st,st+tot)-st;printf("Stan: %d; Ollie:",res);for(int i=0;i<a;i++)printf(" %d",st[i]);printf(";\n");}return 0;
}


这篇关于poj2464Brownie Points II(树状数组)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/955397

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

PHP7扩展开发之数组处理

前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: <?phpfunction array_concat ($arr, $prefix) {foreach($arr as $key => $val) {if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {$arr[