题目大意:有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的更多相关文章

  1. BZOJ2758 : [SCOI2012]Blinker的噩梦

    首先将包含关系建树. 方法是将每个图形拆成上半边和下半边,从左往右扫描线,用Splay从下到上维护扫描线上所有图形. 每次加入一个新的图形$x$的时候,看看它下方第一个图形$y$,如果$y$是上半边, ...

  2. BZOJ 2758 Blinker的噩梦(扫描线+熟练剖分+树状数组)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2758 题意:平面上有n个多边形(凸包和圆).任意两个多边形AB只有两种关系:(1) ...

  3. BZOJ2757 : [SCOI2012]Blinker的仰慕者

    BZOJ AC900题纪念~~ 若K>0,则 设f[i][j]表示i位数字,积为j的数字的个数 g[i][j]表示i位数字,积为j的数字的和 DP+Hash预处理 查询时枚举LCP然后统计贡献 ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. bzoj2758【scoi2012】Blinker的的噩梦

    题目描述 一天Blinker醒来,发现自己成为了一个二维世界的点,而且被标记上了一个奇怪的值. 这个世界是由N个边界互不相交(且不相切)的图形组成,这里图形仅包括圆和凸多边形.每个图形还有一个权值.每 ...

  6. bzoj2757【scoi2012】Blinker的仰慕者

    题目描述 Blinker 有非常多的仰慕者,他给每个仰慕者一个正整数编号.而且这些编号还隐藏着特殊的意义,即编号的各位数字之积表示这名仰慕者对Blinker的重要度. 现在Blinker想知道编号介于 ...

  7. BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3352  Solved: 919[Submit][Stat ...

  8. Bzoj2756 [SCOI2012]奇怪的游戏

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3220  Solved: 886 Description ...

  9. 【BZOJ】【2756】【SCOI2012】奇怪的游戏

    网络流-最大流 这题……建模部分先略过 这道题是会卡时限的T_T俺的Dinic被卡了,在此放几篇很棒的讲网络流算法的文章,至于大家耳熟能详的论文就不放了…… http://www.cppblog.co ...

随机推荐

  1. Python 的stat 模块

    #!/usr/bin/env python#-*- encoding:UTF-8 -*- import os,time,stat fileStats = os.stat ( 'test.txt' )  ...

  2. 2018.09.27 网络协议(tarjan)

    描述 一些学校连接在一个计算机网络上.学校之间存在软件支援协议.每个学校都有它应支援的学校名单(学校 a 支援学校 b ,并不表示学校 b 一定支援学校 a ).当某校获得一个新软件时,无论是直接得到 ...

  3. 2018.08.11 洛谷P3224 [HNOI2012]永无乡(线段树合并)

    传送门 给出n个带点权的点,支持连边和查询连通块第k大. 这个貌似就是一道线段树合并的裸板啊... 代码: #include<bits/stdc++.h> #define N 100005 ...

  4. 32. My Experiences in the Factories 我在工厂的经历

    32. My Experiences in the Factories 我在工厂的经历 ① I've worked in the factories surrounding my hometown e ...

  5. php mysql增删查改

    php mysql增删查改代码段 $conn=mysql_connect('localhost','root','root');  //连接数据库代码 mysql_query("set na ...

  6. 8b10b

    目的:保持直流平衡DC Balance). running disparity() 8bit原始数据会分成两部分,其低5位会进行5B/6B编码,高3位则进行3B/4B编码,这两种映射关系在当时已经成为 ...

  7. Redis Cluster原理初步

    目录 目录 1 1. 前言 1 2. 槽(slots) 1 3. 路由配置(node.conf) 1 4. 总slots数(cluster.h:16384) 2 5. key的路由 2 6. 将key ...

  8. OpenNI检测不到Kinect Camera和Kinect Audio了

    ?? 只有检测到了Kinect Motor(马达)而马达是微软开发的. 那么PrimeSense出了什么问题呢? 我的系统是Win7 64位的. 是由于电源供电出错.

  9. Javascript 中函数的 length 属性

    每个函数都有一个 length属性 (函数名.length), 表示期望接收的函数的个数(而不是实际接收的参数个数) 它与arguments不同. arguments.length 是表示函数实际接收 ...

  10. hdu 5068 线段树维护矩阵乘积

    http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...