Task:

有很多盏灯,第ii盏灯在第ii个时刻点亮。如果有至少kik_i盏灯照亮了第ii盏灯,那么这盏灯就将被点亮。每盏灯照亮的范围都是一样角度的一个区域且无限延伸,给定(x1,y1),(x2,y2)(x1,y1),(x2,y2)表示如果这盏灯的坐标在(x,y)(x,y),那么它的照亮范围为射线(x,y)→(x+x1,y+y1)(x,y)\to (x+x1,y+y1)与射线(x,y)→(x+x2,y+y2)(x,y)\to (x+x2,y+y2)之间的区域。

给定nn盏灯的坐标,kik_i,求每一盏灯被点亮的最早时间。(n<=200000)(n。

Solution:

kxj Orz…

首先所有灯的朝向都是一样的,所以可以直接扭转坐标轴,使得变成一个二维的平面问题。题目非常人性地直接给出了两个向量,这里可以使用这两个向量为基底直接表示平面上的点,转化为一个平面直角坐标系:

设(ai,bi)为转化后的坐标ai(x1,y1)+bi(x2,y2)=(xi,yi){aix1+bix2=xiaiy1+biy2=yi解得⎧⎩⎨ai=xiy2−x2yix1y2−x2y1bi=x1yi−xiy1x1y2−x2y1

\text{设}(a_i,b_i)\text{为转化后的坐标}\\ a_i(x1,y1)+b_i(x2,y2)=(x_i,y_i)\\ \begin{cases} a_ix1+b_ix2=x_i\\ a_iy1+b_iy2=y_i \end{cases}\\ \text{解得} \begin{cases} a_i=\frac{x_iy2-x2y_i}{x1y2-x2y1}\\ b_i=\frac{x1y_i-x_iy1}{x1y2-x2y1}\\ \end{cases}\\
于是我们惊奇的发现分母是一样的,于是可以直接忽略分母。然而还有一个特判的点,本题中光线可能只有一条线,那么将一个向量微小偏移一下,不影响结果,就可以了。

然后现在是一个平面直角坐标系,对于每一个点,它能照亮的区域是右上角的区域。有一种整体二分的做法:

直接二分时间[L,R][L,R]同时[l,r][l,r]为在此段时间内点亮的灯,取Mid=L+R2Mid=\frac{L+R}{2},将[l,r][l,r]划分为[l,mid][l,mid]与[mid+1,r][mid+1,r]表示在MidMid前点亮的灯与在MidMid后点亮的灯,递归求解即可。

那么现在问题是如何求一盏灯是否在MidMid前点亮,关键在于求一盏灯的左下角的灯的数目,这在平面上是一个非常经典的问题。将灯按照xx坐标排序,用树状数组维护yy坐标,横向依次扫描就可以完成了。如果求得的左下角的灯的个数大于等于kk个,或者灯的编号大于等于MidMid,则把它归到[l,mid][l,mid]的区间。

于是就可以解决这道题了,复杂度O(nlog2n)O(nlog^2n)。

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
inline void Rd(int &res){char c;int f=1;res=0;while(c=getchar(),c<'0'&&c!='-');if(c=='-')f=-1,c=getchar();do{res=(res<<1)+(res<<3)+(c^48);}while(c=getchar(),c>='0');res*=f;
}
const int M=200005;
struct Node{int x,y,k,ans,id;bool operator <(const Node &A)const{if(x!=A.x)return x<A.x;else return y<A.y;}
}A[M];
ll X[M],Y[M],Data[M];
int n;
inline bool cmp(Node A,Node B){return A.id<B.id;}
inline void Change(int &x,int &y){//偏移向量int mx=max(abs(x),abs(y));int d=((ll)2e9+mx-1)/mx;x*=d;y*=d;x++;
}
void Init(){for(int i=1;i<=n;i++)Data[i-1]=X[i];sort(Data,Data+n);int sz=unique(Data,Data+n)-Data;for(int i=1;i<=n;i++)A[i].x=lower_bound(Data,Data+sz,X[i])-Data+1;//[1,sz]for(int i=1;i<=n;i++)Data[i-1]=Y[i];sort(Data,Data+n);sz=unique(Data,Data+n)-Data;for(int i=1;i<=n;i++)A[i].y=lower_bound(Data,Data+sz,Y[i])-Data+1;//[1,sz]
}
struct BIT{int val[M];void Add(int x,int v){while(x<=n){val[x]+=v;x+=lowbit(x);}}int Query(int x){int rs=0;while(x){rs+=val[x];x-=lowbit(x);}return rs;}
}BIT;
void solve(int L,int R,int l,int r){if(L==R){for(int i=l;i<=r;i++)A[i].ans=L;return;}int Mid=(L+R)>>1,mid=l-1;sort(A+l,A+r+1);for(int i=l;i<=r;i++){int rs=BIT.Query(A[i].y);if(A[i].id<=Mid||rs>=A[i].k){BIT.Add(A[i].y,1);mid++;swap(A[mid],A[i]);}else A[i].k-=rs;}for(int i=l;i<=mid;i++)BIT.Add(A[i].y,-1);if(l<=mid)solve(L,Mid,l,mid);if(mid+1<=r)solve(Mid+1,R,mid+1,r);
}
int main(){int x1,y1,x2,y2;Rd(n);Rd(x1),Rd(y1),Rd(x2),Rd(y2);if(1LL*x1*y2==1LL*x2*y1)Change(x1,y1);if(1LL*x1*y2<1LL*x2*y1)swap(x1,x2),swap(y1,y2);for(int i=1;i<=n;i++){int x,y;Rd(x),Rd(y);A[i].id=i;X[i]=1LL*x*y2-1LL*x2*y;Y[i]=1LL*x1*y-1LL*x*y1;}for(int i=1;i<=n;i++)Rd(A[i].k);Init();solve(1,n,1,n);sort(A+1,A+n+1,cmp);for(int i=1;i<=n;i++)printf("%d%c",A[i].ans,i==n?'\n':' ');return 0;
}

BZOJ3833[Poi2014] Solar lamps相关推荐

  1. BZOJ3833 : [Poi2014]Solar lamps

    首先旋转坐标系,将范围表示成矩形或者射线 如果范围是一条线,则将灯按y坐标排序,y坐标相同的按x坐标排序, 对于y相同的灯,f[i]=min(i,它前面灯发光时刻的第k[i]小值), 线段树维护,$O ...

  2. POI2014 Solar lamps

    Solar lamps POI2014 题意 1.有n个灯,他们只会朝一个确定的夹角发光 2.每个灯被放在一个固定的地方,并且朝向同一个方向(指如果发光会朝同一个方向) 3.第i盏灯如果被至少K[i] ...

  3. POI2014 Solar Panels

    Solar Panels POI2014 题意 多组询问,每次问x∈[L1,R1],y∈[L2,R2]时,gcd(x, y)的最大值 解 1.设答案为d 那么必须满足 ⌊ L 1 − 1 d ⌋ \l ...

  4. [POI2014]Solar Panels

    题目大意: $T(T\le1000)$组询问,每次给出$A,B,C,D(A,B,C,D\le10^9)$,求满足$A\le x\le B,C\le y\le D$的最大的$\gcd(x,y)$. 思路 ...

  5. BZOJ3834: [Poi2014]Solar Panels

    题目大意:给定A,B,C,D,求满足A≤x≤B&&C≤y≤D的gcd(x,y)的最大值 首先枚举答案n,变成检验 ⌊A−1n⌋ \lfloor\frac{A-1}{n}\rfloor ...

  6. usaco party lamps

    不说什么了这题真的解不出来.看了题解,规律一层套一层,题目越来越难了加油吧. /* ID:jinbo wu PROG:lamps LANG:C++ */ #include<bits/stdc++ ...

  7. 洛谷P3572 [POI2014]PTA-Little Bird

    P3572 [POI2014]PTA-Little Bird 题目描述 In the Byteotian Line Forest there are nn trees in a row. On top ...

  8. P3572 [POI2014]PTA-Little Bird

    P3572 [POI2014]PTA-Little Bird 一只鸟从1跳到n.从1开始,跳到比当前矮的不消耗体力,否则消耗一点体力,每次询问有一个步伐限制k,求每次最少耗费多少体力 很简短的题目哼. ...

  9. [BZOJ3832][Poi2014]Rally

    [BZOJ3832][Poi2014]Rally 试题描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byt ...

最新文章

  1. 11g新特性-SQL Plan Management
  2. Redis.conf常见配置介绍
  3. Promise之异步调用
  4. rspec 测试页面元素_如何使用RSpec对Go应用进行黑盒测试
  5. 算法:由0-5随机数设计0-8随机数
  6. C++primer plus第六版课后编程题答案8.6
  7. nginx学习笔记之安装
  8. Json扩展 (转)
  9. cannon linux驱动下载
  10. NOIP2013 复盘
  11. 用树莓派做一个人脸识别开锁应用
  12. MySQL树结构查询所有叶子节点
  13. Google earth engine(GEE)——LANDSAT8统计不同点的DN值
  14. 证券股票交易接口需要满足什么要求才能在实盘中用?
  15. OSPF协议介绍➌(认证、汇总扩展、LSDB的保护特性、缺省路由、附录E、选路规则、SPF算法、NP+E位、FA地址)
  16. java 字符串不等于_java如何对字符串进行不等于判断
  17. 技术人生:真的要注意身体了,坚持锻炼
  18. JavaScript实现网页关灯效果
  19. 伯德图 matlab,Matlab/Simulink中bode图的画法
  20. 日本僧人问道弘法寺当家师

热门文章

  1. 9.1黑马Vue电商后台管理系统商品管理模块完善:编辑商品的功能
  2. 文件夹加密 隐私加密 就用文件夹加密超级大师
  3. python随机森林
  4. iPhone管理软件iMazing 2.16.9激活密钥免费版百度网盘下载
  5. 关于java异常处理机制的深入理解
  6. crossover卸载 linux,新技能!在Ubuntu 中卸载CrossOver
  7. Cyanine5 azide是一种花青素荧光染料,CAS:2183440-50-6
  8. Java中的JSP是什么?如何实现JSP
  9. Leetcode:给定一个整数,将其转换成罗马数字
  10. 飞机在加速起飞和在空中飞机时的动力是什么提供的?