[BZOJ2758] [SCOI2012]Blinker的噩梦 扫描线+set
题目大意:有n个圆或凸多边形,这些图形不会相交,每当走入或走出一个图形时需要异或上一个代价,有m组操作:
询问操作,每次询问从一个点走到另一个点时,需要的代价(初始代价为0)
修改操作,每次修改一个图形的代价
数据范围:n≤1e5,点权的绝对值不大于1e9
此题真实毒瘤题
考虑到此题图形之间两两互不相交,那么图形与图形之间的关系为相离或包含,包含关系我们可以将其建成一棵树结构。
我们用set来维护一个以x为第一关键字的扫描线,每次扫描到一个新的图形,我们就将该图形拆成上下两部分(可以理解为左右括号),分别加入到set中(考虑到图形不会包含,那么在图形出现的值域内,如果只考虑当前加入的这些图形,这些图形构成的括号序列是不会发生变化的,我们只需要写一个在给定X值情况下能求出图形上下两部分的Y值的函数即可)
然后再做一条射线往上,碰到了另一个多边形,不难发现只会有两种情况:
第一种情况:遇到一个图形的上部分,那么显然碰到的那个图形包含了当前图形。
第二种情况:遇到一个图形的下部分,那么显然当前图形与碰到的图形是相离关系。
当某个图形在扫描线变化后不再出现时,从set中删去这个图形。
(以上说得有点玄乎,感性理解下吧)
我们基于这些关系,建出了一棵树。
对于一个查询操作,显然是查询从树上一个点到另一个点的异或和,考虑到这个值可能会被修改,用树状数组随便维护下就好了
然后就没了,说起来很简单写起来hhh。
注意精度损失!!!!!
#include<bits/stdc++.h>
#define M 300005
#define INF 1e15
#define eps 1e-9
#define D long double
#define sqr(x) ((x)*(x))
#define lowbit(x) ((x)&(-x))
using namespace std; int b[M]={},N,val[M]={};
void updata(int x,int k){ for(int i=x;i<=N;i+=lowbit(i)) b[i]^=k;}
int query(int x){ int k=; for(int i=x;i;i-=lowbit(i)) k^=b[i]; return k;} struct edge{int u,next;}e[M]={}; int head[M]={},use=;
void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
int dfn[M]={},low[M]={},fa[M]={},t=;
void dfs(int x){
dfn[x]=++t;
for(int i=head[x];i;i=e[i].next) dfs(e[i].u);
low[x]=t;
updata(dfn[x],val[x]);
updata(low[x]+,val[x]);
} D nowX; struct node{
int n,down,val,id;
D X,Y,r,x[],y[];
D lx,rx;
void makebig(){X=Y=; r=INF;lx=-INF; rx=INF;}
void rd(int ID){
id=ID;
char op[]; scanf("%s",op);
if(op[]=='C'){
n=; scanf("%Lf%Lf%Lf",&X,&Y,&r);
lx=X-r; rx=X+r;
}else{
scanf("%d",&n);
lx=INF; rx=-INF;
for(int i=;i<=n;i++){
scanf("%Lf%Lf",x+i,y+i);
lx=min(lx,x[i]);
rx=max(rx,x[i]);
}
x[n+]=x[]; y[n+]=y[];
}
scanf("%d",&val);
}
void rd(){
n=-;
scanf("%Lf%Lf",&X,&Y);
lx=rx=X;
}
D get(D now){
D Y1=INF,Y2=-INF;
if(n==-) return Y;
if(n==){
Y1=Y-sqrt(max(sqr(r)-sqr(X-now),(D)0.0));
Y2=Y+sqrt(max(sqr(r)-sqr(X-now),(D)0.0));
}else{
for(int i=;i<=n;i++){
D now1=x[i],now2=x[i+];
if(now1==now2) continue;
if(now1>now2) swap(now1,now2);
if(!(now1-eps<=now&&now<=now2+eps)) continue;
D k=(y[i+]-y[i])/(x[i+]-x[i]);
D nowy=y[i]+(now-x[i])*k;
Y1=min(Y1,nowy);
Y2=max(Y2,nowy);
}
}
if(down) return Y1;
return Y2;
}
friend bool operator <(node a,node b){
D vala=a.get(nowX);
D valb=b.get(nowX);
if(fabs(vala-valb)>eps) return vala<valb;
return a.down>b.down;
}
}a[M];
set<node> s;
int n,m,q; void pushset(node now){
now.down=; s.insert(now);
now.down=; s.insert(now);
}
void popset(node now){
now.down=; s.erase(now);
now.down=; s.erase(now);
} struct hh{
int id,zf; hh(int ID=,int ZF=){id=ID; zf=ZF;}
friend bool operator <(hh x,hh y){
D valx,valy;
if(x.zf==-) valx=a[x.id].lx; else valx=a[x.id].rx;
if(y.zf==-) valy=a[y.id].lx; else valy=a[y.id].rx;
return valx<valy;
}
}p[M*]={}; int pointsum=;
int chx[M]={},chval[M]={},id1[M]={},id2[M]={}; int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
a[].makebig(); fa[]=-;
nowX=-INF; pushset(a[]);
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++) a[++pointsum].rd(i); for(int i=;i<=n;i++) val[i]=a[i].val;
for(int i=;i<=n;i++) p[++m]=hh(i,),p[++m]=hh(i,-); for(int i=;i<=q;i++){
char op[]; scanf("%s",op);
if(op[]=='C'){scanf("%d%d",chx+i,chval+i);}
else{
a[++pointsum].rd();
p[++m]=hh(pointsum,);
id1[i]=pointsum; a[++pointsum].rd();
p[++m]=hh(pointsum,);
id2[i]=pointsum;
}
} sort(p+,p+m+);
N=m+;
for(int x=;x<=m;x++){
int id=p[x].id;
//cout<<s.size()<<endl;
if(p[x].zf==-) nowX=a[id].lx; else nowX=a[id].rx;
if(p[x].zf==-||p[x].zf==){
pushset(a[id]);
set<node>::iterator it=s.find(a[id]); it++;
if(it->down)
fa[id]=fa[it->id];
else fa[id]=it->id; if(p[x].zf==)
popset(a[id]);
}else{
popset(a[id]);
}
}
for(int i=;i<=m;i++) add(fa[i],i);
dfs();
int ans=;
for(int i=;i<=q;i++){
// if(chx[i]) continue;
if(chx[i]){
int x=chx[i],zhi=chval[i];
updata(dfn[x],val[x]);
updata(low[x]+,val[x]);
val[x]=zhi;
updata(dfn[x],val[x]);
updata(low[x]+,val[x]);
}else{
int ans1=query(dfn[id1[i]]);
int ans2=query(dfn[id2[i]]);
ans=ans^ans1^ans2;
printf("%d\n",ans);
}
}
// return 0;
}
[BZOJ2758] [SCOI2012]Blinker的噩梦 扫描线+set的更多相关文章
- BZOJ2758 : [SCOI2012]Blinker的噩梦
首先将包含关系建树. 方法是将每个图形拆成上半边和下半边,从左往右扫描线,用Splay从下到上维护扫描线上所有图形. 每次加入一个新的图形$x$的时候,看看它下方第一个图形$y$,如果$y$是上半边, ...
- BZOJ 2758 Blinker的噩梦(扫描线+熟练剖分+树状数组)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2758 题意:平面上有n个多边形(凸包和圆).任意两个多边形AB只有两种关系:(1) ...
- BZOJ2757 : [SCOI2012]Blinker的仰慕者
BZOJ AC900题纪念~~ 若K>0,则 设f[i][j]表示i位数字,积为j的数字的个数 g[i][j]表示i位数字,积为j的数字的和 DP+Hash预处理 查询时枚举LCP然后统计贡献 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- bzoj2758【scoi2012】Blinker的的噩梦
题目描述 一天Blinker醒来,发现自己成为了一个二维世界的点,而且被标记上了一个奇怪的值. 这个世界是由N个边界互不相交(且不相切)的图形组成,这里图形仅包括圆和凸多边形.每个图形还有一个权值.每 ...
- bzoj2757【scoi2012】Blinker的仰慕者
题目描述 Blinker 有非常多的仰慕者,他给每个仰慕者一个正整数编号.而且这些编号还隐藏着特殊的意义,即编号的各位数字之积表示这名仰慕者对Blinker的重要度. 现在Blinker想知道编号介于 ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3352 Solved: 919[Submit][Stat ...
- Bzoj2756 [SCOI2012]奇怪的游戏
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3220 Solved: 886 Description ...
- 【BZOJ】【2756】【SCOI2012】奇怪的游戏
网络流-最大流 这题……建模部分先略过 这道题是会卡时限的T_T俺的Dinic被卡了,在此放几篇很棒的讲网络流算法的文章,至于大家耳熟能详的论文就不放了…… http://www.cppblog.co ...
随机推荐
- DB2自增长ID
建议类似的应用采用sequence对象,将来的应用维护和数据迁移会很方便.考虑的因素较少. 对于序列可以使用nextval和prevval来获得下一个和上一个值:CREATE SEQUENCE seq ...
- ubuntu16下Elasticsearch5.1.1安装部署
本人在安装es5.1.1版本时候整理的一些过程,参照了网上部分过程:其中过程中也出现一些其它问题,出现的问题和解决方案都整理在此文中. 1Elasticsearch5.1.1安装 到ES官网https ...
- 二叉树的遍历——Morris
在之前的博客中,博主讨论过二叉树的经典遍历算法,包括递归和常规非递归算法,其时间复杂度和空间复杂度均为O(n).Morris算法巧妙地利用了二叉树的线索化思路,将二叉树的遍历算法的空间复杂度降低为O( ...
- Android中px, ppi, dpi, dp, dip, sp概念解析
Android中px, ppi, dpi, dp, dip, sp概念解析
- SEO方式之HTTPS 访问优化详解
SEO到底要不要做HTTPS?HTTPS对SEO的重要性 正方观点 1.HTTPS具有更好的加密性能,避免用户信息泄露: 2.HTTPS复杂的传输方式,降低网站被劫持的风险: 3.搜索引擎已经全面支持 ...
- 2018.07.28 uoj#164. 【清华集训2015】V(线段树)
传送门 线段树好题. 要求支持的操作: 1.区间变成max(xi−a,0)" role="presentation" style="position: rela ...
- VMware + LInux + Xshell 连接环境设置(心得体会)
准备好VMware软件,和Linux 和xshell三款软件,下载和安装好,这里VMware是十二,Linux是CentOs 6 ,xshell是5 其实没有什么区别只要版本兼容就行,我们就可以实现远 ...
- day4之装饰器进阶、生成器迭代器
装饰器进阶 带参数的装饰器 # 某一种情况# 500个函数加装饰器, 加完后不想再加这个装饰器, 再过一个季度,又想加上去# 你可以设计你的装饰器,来确认是否执行 # 第一种情况 # 想要500个函数 ...
- MySQL性能调优与架构设计——第12章 可扩展设计的基本原则
第12章 可扩展设计的基本原则 前言: 随着信息量的飞速增加,硬件设备的发展已经慢慢的无法跟上应用系统对处理能力的要求了.此时,我们如何来解决系统对性能的要求?只有一个办法,那就是通过改造系统的架构体 ...
- Ubuntu16.04安装PostgreSQL并使用pgadmin3管理数据库_图文详解
版权声明:本文地址http://blog.csdn.net/caib1109/article/details/51582663 欢迎非商业目的的转载, 作者保留一切权利 apt安装postgresql ...