bzoj2758【scoi2012】Blinker的的噩梦
题目描述
输入格式
输出格式
1<=N<=100000,1<=M<=100000,单个凸多边形的点数小于等于34。图形互不相交,且Blinker的出发点和目的地不在图形的边界。
题解:
- 由于只有包含和相离所以是一个树形结构,只需要找到每个图形的父亲建树;
- 询问即树链上的异或和,BIT维护即可;
- 将每个多边形分成上壳和下壳;
- 按$x$坐标扫描,图不相交,有个性质:一旦加入图形的上下关系就是确定的,$splay$维护$y$坐标的大小;
- 查询$(x,y)$可以直接在扫描到$x$的时候查找$y$的前驱,如果是下壳则就是查到的图形,否则是它的父亲;
- 点定位和图形定位都是这个思路;
- 我看的Claris的题解,自己写了,改了两天一直只有30,又不会造数据,不得已只能照着代码改成和$std$要像不像的才过了。。。。TAT
- 至今不知道自己错哪里了。。。。
#include<bits/stdc++.h>
#define ld double
using namespace std;
const int N=;
const ld inf=1e20,eps=1e-;
int n,m,cnt,tot,o=,hd[N],f[N],st[N],ed[N],idx,c[N],rt,ch[N<<][],fa[N<<],bl[N<<];
ld X;
struct Edge{int v,nt;}E[N<<];
char s[];
struct P{
ld x,y;
P(ld _x=,ld _y=):x(_x),y(_y){};
bool operator <(const P&a)const{return x==a.x?y<a.y:x<a.x;}
}q[N<<];
struct line{ld x;int id,typ;}B[N<<];
struct Graph{
int typ,w;
int n;P p[];
P O;ld R;
void init(){
scanf("%s",s+);
typ=s[]=='P';
if(!typ)scanf("%lf%lf%lf%d",&O.x,&O.y,&R,&w);
else{
scanf("%d",&n);
for(int j=;j<n;++j)scanf("%lf%lf",&p[j].x,&p[j].y);
scanf("%d",&w);
p[n]=p[];
}
}
ld getl(){
if(!typ)return O.x-R;
ld re=inf;
for(int i=;i<n;++i)re=min(re,p[i].x);
return re;
}
ld getr(){
if(!typ)return O.x+R;
ld re=-inf;
for(int i=;i<n;++i)re=max(re,p[i].x);
return re;
}
ld cal0(ld x){
if(!typ)return O.y+sqrt(max(R*R-(x-O.x)*(x-O.x),0.0));
ld re=-inf;
for(int i=;i<n;++i){
ld A=p[i].x,B=p[i].y,C=p[i+].x,D=p[i+].y;
if(A>C)swap(A,C),swap(B,D);
if(x<A-eps||x>C+eps)continue;
if(x<A+eps){re=max(re,B);continue;}
if(x>C-eps){re=max(re,D);continue;}
re=max(re,B+(D-B)/(C-A)*(x-A));
}
return re;
}
ld cal1(ld x){
if(!typ)return O.y-sqrt(max(R*R-(x-O.x)*(x-O.x),0.0));
ld re=inf;
for(int i=;i<n;++i){
ld A=p[i].x,B=p[i].y,C=p[i+].x,D=p[i+].y;
if(A>C)swap(A,C),swap(B,D);
if(x<A-eps||x>C+eps)continue;
if(x<A+eps){re=min(re,B);continue;}
if(x>C-eps){re=min(re,D);continue;}
re=min(re,B+(D-B)/(C-A)*(x-A));
}
return re;
}
}A[N];
struct Query{int typ,u,v,x;}C[N];
bool cmpB(const line&a,const line&b){
if(a.typ&&b.typ&&a.id==b.id)return a.typ>b.typ;
return a.x<b.x;
}
bool cmp1(int k,ld y){
if(k==(n<<|))return ;
if(k==(n<<))return ;
ld t=k&?A[k>>].cal1(X):A[k>>].cal0(X);
return t<y;
}
bool cmp2(int x,int y){
if(x==(n<<|))return ;
if(x==(n<<))return ;
if((x^y)==)return x&;
ld t1=x&?A[x>>].cal1(X):A[x>>].cal0(X),
t2=y&?A[y>>].cal1(X):A[y>>].cal0(X);
return t1<t2;
}
void rotate(int x,int&k){
int y=fa[x],z=fa[y];
if(y!=k)ch[z][ch[z][]==y]=x;else k=x;
int l=ch[y][]==x,r=l^;
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r],ch[x][r]=y;
}
void splay(int x,int&k){
for(int y,z;x!=k;rotate(x,k)){
y=fa[x],z=fa[y];
if(y!=k)rotate((ch[z][]==y)^(ch[y][]==x) ? x : y , k);
}
}
void adde(int u,int v){
E[o]=(Edge){v,hd[u]};
f[v]=u;hd[u]=o++;
}
void ins(int&k,int x){
if(!k){k=x;return;}
int d=cmp2(k,x);
ins(ch[k][d],x);
fa[ch[k][d]]=k;
}
int find(ld y){
int k=rt,re=;
while(k){
if(cmp1(k,y))re=k,k=ch[k][];
else k=ch[k][];
}return re;
}
void add(int x){
/*if(x==20193){
puts("haha");
}*/
int p=x<<,q=p|;
ins(rt,p);ins(rt,q);
splay(q,rt);
int t=ch[q][];
while(ch[t][])t=ch[t][];
adde(t&?t>>:f[t>>],x);
splay(t,rt);
}
void del(int x){
splay(x,rt);
int y=ch[x][];
while(ch[y][])y=ch[y][];
splay(y,ch[x][]);
ch[y][]=ch[x][];
fa[ch[x][]]=y;
fa[rt=y]=;
}
void getp(int x){
int t=find(q[x].y);
bl[x]=t&?t>>:f[t>>];
splay(t,rt);
}
void mfy(int x,int y){for(;x<=n;x+=x&-x)c[x]^=y;}
int ask(int x){int re=;for(;x;x-=x&-x)re^=c[x];return re;}
void upd(int x,int y){
swap(y,A[x].w);y^=A[x].w;
mfy(st[x],y);mfy(ed[x]+,y);
}
int que(int x){return ask(st[x]);}
void dfs(int u){
st[u]=++idx;
mfy(st[u],A[u].w);
for(int i=hd[u];i;i=E[i].nt)dfs(E[i].v);
ed[u]=idx;
mfy(ed[u]+,A[u].w);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("T3.in","r",stdin);
freopen("T3.out","w",stdout);
#endif
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i){
A[i].init();
B[++cnt]=(line){A[i].getl(),i,};
B[++cnt]=(line){A[i].getr(),i,-};
}
for(int i=;i<=m;++i){
scanf("%s",s+);
C[i].typ=s[]=='Q';
if(!C[i].typ)scanf("%d%d",&C[i].u,&C[i].x);
else{
C[i].u=++tot,scanf("%lf%lf",&q[tot].x,&q[tot].y);
B[++cnt]=(line){q[tot].x,tot,};
C[i].v=++tot,scanf("%lf%lf",&q[tot].x,&q[tot].y);
B[++cnt]=(line){q[tot].x,tot,};
}
}
sort(B+,B+cnt+,cmpB);
++n;
ch[rt=n<<][]=n<<|;
fa[n<<|]=n<<;
for(int i=;i<=cnt;++i){
X=B[i].x;
if(B[i].typ==)add(B[i].id);
else if(B[i].typ==-)del(B[i].id<<),del(B[i].id<<|);
else getp(B[i].id);
}
dfs(n);
int ans=;
for(int i=;i<=m;++i)if(C[i].typ){
ans^=que(bl[C[i].u])^que(bl[C[i].v]);
printf("%d\n",ans);
}else upd(C[i].u,C[i].x);
return ;
}
#include<bits/stdc++.h>
#define ld double
using namespace std;
const int N=;
inline int M(int x,int y){return (x+y)%y;}
const ld eps=1e-;
int n,m,cnt,tot;
char s[];
struct P{
ld x,y;int id;
P(ld _x=,ld _y=,int _id=):x(_x),y(_y),id(_id){};
bool operator <(const P&a)const{return x==a.x?y<a.y:x<a.x;}
}q[N<<];
struct line{ld x;int id,typ;}B[N<<];
struct Graph{
int typ,w;
int n,t1,t2,l,r;P p[];
P O;ld R;
void init(int i){
scanf("%s",s+);
typ=s[]=='P';
if(!typ){
scanf("%lf%lf%lf%d",&O.x,&O.y,&R,&w);
B[++cnt]=(line){O.x-R,i,};
B[++cnt]=(line){O.x+R,i,-};
}
else{
scanf("%d",&n);
scanf("%lf%lf",&p[].x,&p[].y);
l=;r=;
for(int j=;j<n;++j){
scanf("%lf%lf",&p[j].x,&p[j].y);
if(p[j].x<p[l].x)l=j;
if(p[j].x>p[r].x)r=j;
}
t1=t2=l;
while(fabs(p[t1].x-p[M(t1+,n)].x)<eps)t1=M(t1+,n); //
while(fabs(p[t2].x-p[M(t2-,n)].x)<eps)t2=M(t2-,n); //
scanf("%d",&w);
B[++cnt]=(line){p[l].x,i,};
B[++cnt]=(line){p[r].x,i,-};
}
}
}A[N];
struct Query{
int typ;
int u,v,x;
void init(int i){
scanf("%s",s+);
typ=s[]=='Q';
if(!typ)scanf("%d%d",&u,&x);
else{
q[++tot].id=i<<;
scanf("%lf%lf",&q[tot].x,&q[tot].y);
q[++tot].id=i<<|;
scanf("%lf%lf",&q[tot].x,&q[tot].y);
}
}
}C[N];
bool cmpB(const line&a,const line&b){return fabs(a.x-b.x)<eps?a.typ>b.typ:a.x<b.x;}
ld cal(int k,ld x){
int i=k>>;
if(!A[i].typ){
P O = A[i].O;
ld d=sqrt(A[i].R*A[i].R - (x-O.x)*(x-O.x) + eps);//
return k&?O.y-d:O.y+d;
}else{
int&t=k&?A[i].t2:A[i].t1,ad=k&?-:;
while(t!=A[i].r&&A[i].p[M(t+ad,A[i].n)].x<x-eps)t=M(t+ad,A[i].n);//
P p1=A[i].p[t],p2=A[i].p[M(t+ad,A[i].n)];
return p1.y+(x-p1.x)/(p2.x-p1.x)*(p2.y-p1.y);
}
}
bool cmpA(int k,ld x,ld y){
if(k==(n<<|))return ;
if(k==(n<<))return ;
return cal(k,x)<=y;
}
namespace Splay{
int rt,ch[N<<][],fa[N<<];
void init(){
int p=n<<,q=n<<|;
ch[rt=p][]=q;
fa[q]=p;
}
void rotate(int x,int&k){
int y=fa[x],z=fa[y];
if(y!=k)ch[z][ch[z][]==y]=x;else k=x;
int l=ch[y][]==x,r=l^;
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r],ch[x][r]=y;
}
void splay(int x,int&k){
for(int y,z;x!=k;rotate(x,k)){
y=fa[x],z=fa[y];
if(y!=k)rotate((ch[z][]==y)^(ch[y][]==x) ? x : y , k);
}
}
int find(ld x,ld y){
int k=rt,re=;
while(k){
if(cmpA(k,x,y))re=k,k=ch[k][];
else k=ch[k][];
}splay(re,rt);
return re;
}
void ins(int i){
int t=ch[rt][];
while(ch[t][])t=ch[t][];
{
splay(t,ch[rt][]);
}
int p=i<<,q=p|;
ch[t][]=p;fa[p]=t;
ch[p][]=q;fa[q]=p;
{
splay(q,rt);
}
}
/*
void del(int i){
int p=i<<1,q=i<<1|1;
splay(p,rt);
splay(q,ch[p][0]);
int t=ch[q][0];
while(ch[t][1])t=ch[t][1];
splay(t,ch[q][0]);
ch[t][1]=ch[p][1];
fa[ch[p][1]]=t;
fa[rt=t]=0;
}
*/
void del(int x){
splay(x,rt);
int y=ch[x][];
while(ch[y][])y=ch[y][];
splay(y,ch[x][]);
ch[y][]=ch[x][];
fa[ch[x][]]=y;
fa[rt=y]=;
}
}
namespace BIT{
int o=,hd[N],fa[N],st[N],ed[N],idx,c[N];
struct Edge{int v,nt;}E[N];
void adde(int u,int v){E[o]=(Edge){v,hd[u]};hd[u]=o++;}
void add(int x,int y){for(;x<=n;x+=x&-x)c[x]^=y;}
int ask(int x){int re=;for(;x;x-=x&-x)re^=c[x];return re;}
void upd(int x,int y){
swap(y,A[x].w);y^=A[x].w;
add(st[x],y);add(ed[x]+,y);
}
int que(int x){return ask(st[x]);}
void dfs(int u){
st[u]=++idx;
add(st[u],A[u].w);
for(int i=hd[u];i;i=E[i].nt)dfs(E[i].v);
ed[u]=idx;
add(ed[u]+,A[u].w);
}
}
namespace IO{
int sta[],top;
char s[],*p=s;
void push(char x){
if(p==s+)fwrite(s,,,stdout),p=s;
*p++=x;
}
void write(int x){
if(!x){push('');push('\n');return;}
while(x)sta[++top]=x%,x/=;
while(top)push(sta[top--]^'');
push('\n');
}
void flush(){fwrite(s,,p-s,stdout);}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("nightmare.in","r",stdin);
freopen("nightmare.out","w",stdout);
#endif
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)A[i].init(i);
for(int i=;i<=m;++i)C[i].init(i);
sort(B+,B+cnt+,cmpB);
sort(q+,q+tot+);
n++;Splay::init();
int j=;
for(int i=;i<=cnt;++i){
while(j<=tot&&q[j].x<=B[i].x){
int t=Splay::find(q[j].x,q[j].y),bl;
if(t&)bl=t>>;else bl=BIT::fa[t>>];
if(q[j].id&)C[q[j].id>>].v=bl;
else C[q[j].id>>].u=bl;
j++;
}
if(B[i].typ==){
int pos=B[i].id;
int t=Splay::find(B[i].x , A[pos].typ? A[pos].p[A[pos].l].y : A[pos].O.y);
if(t&)BIT::adde(t>>,pos),BIT::fa[pos]=t>>;
else BIT::adde(BIT::fa[t>>],pos),BIT::fa[pos]=BIT::fa[t>>];
Splay::ins(pos);
}else Splay::del(B[i].id<<),Splay::del(B[i].id<<|);
}
while(j<=tot){
if(q[j].id&)C[q[j].id>>].v=n;
else C[q[j].id>>].u=n;
j++;
}
BIT::dfs(n);
/*{
for(int i=1;i<n;++i)printf("%d\n",BIT::fa[i]==n?0:BIT::fa[i]);
}*/
int ans=;
for(int i=;i<=m;++i)if(C[i].typ){
int tmp=;
tmp^=BIT::que(C[i].u);
tmp^=BIT::que(C[i].v);
ans^=tmp;
IO::write(ans);
}else BIT::upd(C[i].u,C[i].x);
IO::flush();
return ;
}
(WA)
bzoj2758【scoi2012】Blinker的的噩梦的更多相关文章
- BZOJ2758 : [SCOI2012]Blinker的噩梦
首先将包含关系建树. 方法是将每个图形拆成上半边和下半边,从左往右扫描线,用Splay从下到上维护扫描线上所有图形. 每次加入一个新的图形$x$的时候,看看它下方第一个图形$y$,如果$y$是上半边, ...
- [BZOJ2758] [SCOI2012]Blinker的噩梦 扫描线+set
题目大意:有n个圆或凸多边形,这些图形不会相交,每当走入或走出一个图形时需要异或上一个代价,有m组操作: 询问操作,每次询问从一个点走到另一个点时,需要的代价(初始代价为0) 修改操作,每次修改一个图 ...
- 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 ...
- bzoj2757【scoi2012】Blinker的仰慕者
题目描述 Blinker 有非常多的仰慕者,他给每个仰慕者一个正整数编号.而且这些编号还隐藏着特殊的意义,即编号的各位数字之积表示这名仰慕者对Blinker的重要度. 现在Blinker想知道编号介于 ...
- BZOJ 2758 Blinker的噩梦(扫描线+熟练剖分+树状数组)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2758 题意:平面上有n个多边形(凸包和圆).任意两个多边形AB只有两种关系:(1) ...
- 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 ...
随机推荐
- 基于openvswitch+Docker构建SDN网络测试环境 (使用ovs-docker进行构建)
这是一篇之前写的笔记,主要记录了使用openvswitch + Docker 等进行一个小型的SDN网络搭建的操作步骤.由于 之前临时有其他任务,耽搁了一下,最近开始重新整理,并计划开发一个简单的Py ...
- 进阶:2.GBDT算法梳理
GBDT算法梳理 学习内容: 1.前向分布算法 2.负梯度拟合 3.损失函数 4.回归 5.二分类,多分类 6.正则化 7.优缺点 8.sklearn参数 9.应用场景 1.前向分布算法 在学习模型时 ...
- 程序设计 之 C#实现《拼图游戏》 (上)代码篇
原理详解请参考博客中 拼图游戏(下)原理篇 http://www.cnblogs.com/labixiaohei/p/6713761.html 功能描述: 1.用户自定义上传图片 2.游戏难度选择:简 ...
- Tomcat分析
最近闲来无事,总结了一下tomcat的一些知识,分享出来供大家参考,如有错误,请及时与我联系. 1. 入门示例:虚拟主机提供web服务 该示例通过设置虚拟主机来提供web服务,因为是入门示例,所以设置 ...
- M1阶段的开发过程的一些反思
今天八组队伍都做了项目的展示,和他们相比,我们的团队项目是显得最单薄的了,这里面的原因很多,固然我们团队整体的实力 比较弱,但是我们在M1项目开发过程中的种种错误表现也是导致我们项目失利的重要原因.下 ...
- Sprint会议2
昨天:准备查找安卓APP开发的有关资料,安装有关软件 今天:自己制作一个安卓小程序,熟悉一下操作 遇到问题:安装遇到问题,环境配置出现问题
- 404 Note Found 团队会议纪要
目录 团队会议 会议纪要1 会议纪要2 会议纪要3 会议纪要4 会议纪要5 会议纪要6 团队会议 会议纪要1 会议纪要2 会议纪要3 会议纪要4 会议纪要5 会议纪要6
- Scrum 项目7.0——第一个Sprint的总结和读后感
总结: 通过这一次的Sprint,我了解了Sprint的整个流程,也学会了编制backlog,也了解了在软件工程中,一个团队的任务是怎么样分配和一个项目是怎么样开展的.从对软件工程的认识只 ...
- loadrunner在win10破解提示:Cannot save the license information because acceses to the registry is denied的解决办法
方法1 下图1-1中提示就是说明了破解的时候权限不足导致,解决办法就是使用管理员权限打开loadrunner破解就好了,但是右键“以管理员身份运行”选项打开loadrunner又是会提示1-2中的问题 ...
- 基于html5的多图片上传,预览
基于html5的多图片上传 本文是建立在张鑫旭大神的多文图片传的基础之上. 首先先放出来大神多图片上传的博客地址:http://www.zhangxinxu.com/wordpress/2011/09 ...