[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 ...
随机推荐
- 如何修改路由器的登录IP地址?
如何修改路由器的登录IP地址? 因为有多个路由器,为了区分不同路由器,我们可以修改它的登录IP,而且修改后,可以在连接的电脑上直观地知道所连接的是哪一台路由器 买回来的路由器,一般默认的登录地址是19 ...
- 前端之JavaScript笔记2
一 数组对象 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- Yii框架请求
$request = Yii::$app->request; $get = $request->get(); // 等价于: $get = $_GET; $id = $request-&g ...
- hdu-1069(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069 题意:一群猴子,给出n块砖的长x宽y高z,用这些砖拼起的高度最高是多少, 要求底下的砖的长宽都要 ...
- PCL(point cloud library) 学习——简介
Point Cloud Library (PCL) 是开源点云处理库, 包括 filtering, feature estimation, surface reconstruction, regist ...
- JavaNIO学习一
文章来源:http://cucaracha.iteye.com/blog/2041847 对文件来说,可能最常用的操作就是创建.读取和写出.NIO.2 提供了丰富的方法来完成这些任务.本文从简单的小文 ...
- I2C笔记
SCL:上升沿将数据输入到每个EEPROM器件中:下降沿驱动EEPROM器件输出数据.(边沿触发) SDA:双向数据线,为OD门,与其它任意数量的OD与OC门成"线与"关系. ...
- java web 入门实例servlet篇(显示后台数据库列表,删除某一条记录并显示)
编写过程中需要注意的问题: 1.建立eclipse动态web工程时,需要改写编译后class文件的位置,通常情况下是这个位置:/WebContent/WEB-INF/classes 2.配置的页面链接 ...
- unlimited channel buffer in Go
channel buffer可以事先分配大小,但是这些是需要占用内存的,事先分配几G内存给一个channel很浪费资源的,所以怎样创建一个无限的channel buffer呢?比较naive的写法就是 ...
- [Openwrt 项目开发笔记]:Samba服务&vsFTP服务(四)
[Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在上一节中,我们讲述了如何在路由器上挂载U盘,以 ...