BZOJ2758 : [SCOI2012]Blinker的噩梦
首先将包含关系建树。
方法是将每个图形拆成上半边和下半边,从左往右扫描线,用Splay从下到上维护扫描线上所有图形。
每次加入一个新的图形$x$的时候,看看它下方第一个图形$y$,如果$y$是上半边,那么$x$的父亲就是$y$,否则是$y$的父亲。用同样的方法可以完成点定位。
然后每次相当于查询两点间的异或和,用树状数组维护dfs序即可。
时间复杂度$O((n+m)\log n)$。
- #include<cstdio>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- const int N=100010,M=N*2;
- const double inf=1e20;
- const double eps=1e-9;
- int n,m,i,x,y,val[N],ce,cb,q[N][3],ans;double X;
- struct Shape{
- bool type;
- double x,y,r,a[35][2];
- int n;
- void read(){
- char t[5];
- scanf("%s",t);
- if(t[0]=='C')type=0,scanf("%lf%lf%lf",&x,&y,&r);
- else{
- type=1;
- scanf("%d",&n);
- for(int i=0;i<n;i++)scanf("%lf%lf",&a[i][0],&a[i][1]);
- a[n][0]=a[0][0],a[n][1]=a[0][1];
- }
- }
- double getl(){
- if(!type)return x-r;
- double ret=inf;
- for(int i=0;i<n;i++)ret=min(ret,a[i][0]);
- return ret;
- }
- double getr(){
- if(!type)return x+r;
- double ret=-inf;
- for(int i=0;i<n;i++)ret=max(ret,a[i][0]);
- return ret;
- }
- double getd(double o){
- if(!type)return y-sqrt(max(r*r-(o-x)*(o-x),0.0));
- double ret=inf;
- for(int i=0;i<n;i++){
- double A=a[i][0],B=a[i][1],C=a[i+1][0],D=a[i+1][1];
- if(A>C)swap(A,C),swap(B,D);
- if(o<A-eps||o>C+eps)continue;
- if(o<A+eps){
- ret=min(ret,B);
- continue;
- }
- if(o>C-eps){
- ret=min(ret,D);
- continue;
- }
- ret=min(ret,B+(D-B)/(C-A)*(o-A));
- }
- return ret;
- }
- double getu(double o){
- if(!type)return y+sqrt(max(r*r-(o-x)*(o-x),0.0));
- double ret=-inf;
- for(int i=0;i<n;i++){
- double A=a[i][0],B=a[i][1],C=a[i+1][0],D=a[i+1][1];
- if(A>C)swap(A,C),swap(B,D);
- if(o<A-eps||o>C+eps)continue;
- if(o<A+eps){
- ret=max(ret,B);
- continue;
- }
- if(o>C-eps){
- ret=max(ret,D);
- continue;
- }
- ret=max(ret,B+(D-B)/(C-A)*(o-A));
- }
- return ret;
- }
- }a[N];
- struct E{
- double x;int y,t;
- E(){}
- E(double _x,int _y,int _t){x=_x,y=_y,t=_t;}
- }e[N*4];
- inline bool cmp(const E&a,const E&b){
- if(a.t<2&&b.t<2&&a.y==b.y)return a.t<b.t;
- return a.x<b.x;
- }
- struct P{double x,y;}b[M];
- int from[M],son[M][2],f[M],root,L,R,fa[N],g[N],v[M],nxt[M],ed,st[N],en[N],dfn,bit[M];
- inline void rotate(int x){
- int y=f[x],w=son[y][1]==x;
- son[y][w]=son[x][w^1];
- if(son[x][w^1])f[son[x][w^1]]=y;
- if(f[y]){
- int z=f[y];
- if(son[z][0]==y)son[z][0]=x;
- if(son[z][1]==y)son[z][1]=x;
- }
- f[x]=f[y];son[x][w^1]=y;f[y]=x;
- }
- inline void splay(int x,int w){
- while(f[x]!=w){
- int y=f[x];
- if(f[y]!=w){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
- rotate(x);
- }
- if(!w)root=x;
- }
- inline bool bigger(int x,int y){
- if(y==L)return 1;
- if(y==R)return 0;
- if(x+n==y||x==y+n)return x>y;
- double A=x<=n?a[x].getd(X):a[x-n].getu(X),
- B=y<=n?a[y].getd(X):a[y-n].getu(X);
- return A>B;
- }
- inline bool biggerp(double x,int y){
- if(y==L)return 1;
- if(y==R)return 0;
- double B=y<=n?a[y].getd(X):a[y-n].getu(X);
- return x>B;
- }
- void ins(int x,int y){
- int w=bigger(y,x);
- if(!son[x][w]){son[x][w]=y;f[y]=x;return;}
- ins(son[x][w],y);
- }
- int ask(int x,double y){
- if(!x)return 0;
- if(biggerp(y,x)){
- int t=ask(son[x][1],y);
- return t?t:x;
- }
- return ask(son[x][0],y);
- }
- inline void add(int x){
- ins(root,x);
- ins(root,x+n);
- splay(x,0);
- int y;
- for(y=son[x][0];son[y][1];y=son[y][1]);
- if(y<L)fa[x]=y<=n?y:fa[y-n];
- splay(y,0);
- }
- inline void del(int x){
- splay(x,0);
- int y;
- for(y=son[x][0];son[y][1];y=son[y][1]);
- splay(y,x);
- son[y][1]=son[x][1];
- f[son[x][1]]=y;
- f[root=y]=0;
- }
- inline void getpos(int x){
- int y=ask(root,b[x].y);
- if(y<L)from[x]=y<=n?y:fa[y-n];
- splay(y,0);
- }
- void dfs(int x){
- st[x]=++dfn;
- for(int i=g[x];i;i=nxt[i])dfs(i);
- en[x]=++dfn;
- }
- inline void modify(int x,int y){for(;x<=dfn;x+=x&-x)bit[x]^=y;}
- inline int sum(int x){int t=0;for(;x;x-=x&-x)t^=bit[x];return t;}
- int main(){
- scanf("%d%d",&n,&m);
- for(i=1;i<=n;i++){
- a[i].read();
- scanf("%d",&val[i]);
- e[++ce]=E(a[i].getl(),i,0);
- e[++ce]=E(a[i].getr(),i,1);
- }
- for(i=1;i<=m;i++){
- char op[5];
- scanf("%s",op);
- if(op[0]=='Q'){
- cb++;
- scanf("%lf%lf",&b[cb].x,&b[cb].y);
- e[++ce]=E(b[cb].x,cb,2);
- cb++;
- scanf("%lf%lf",&b[cb].x,&b[cb].y);
- e[++ce]=E(b[cb].x,cb,2);
- q[i][1]=cb-1,q[i][2]=cb;
- }else{
- q[i][0]=1;
- scanf("%d%d",&q[i][1],&q[i][2]);
- }
- }
- sort(e+1,e+ce+1,cmp);
- L=n*2+1;R=L+1;
- son[L][1]=R,f[R]=L;
- root=L;
- for(i=1;i<=ce;i++){
- X=e[i].x;
- if(!e[i].t)add(e[i].y);
- else if(e[i].t==1)del(e[i].y),del(e[i].y+n);
- else getpos(e[i].y);
- }
- for(i=1;i<=n;i++)if(fa[i])nxt[i]=g[fa[i]],g[fa[i]]=i;
- for(i=1;i<=n;i++)if(!fa[i])dfs(i);
- for(i=1;i<=n;i++)modify(st[i],val[i]),modify(en[i],val[i]);
- for(i=1;i<=m;i++)if(q[i][0]){
- x=q[i][1],y=q[i][2]^val[x];
- val[x]=q[i][2];
- modify(st[x],y),modify(en[x],y);
- }else printf("%d\n",ans^=sum(st[from[q[i][1]]])^sum(st[from[q[i][2]]]));
- return 0;
- }
BZOJ2758 : [SCOI2012]Blinker的噩梦的更多相关文章
- [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 2758 Blinker的噩梦(扫描线+熟练剖分+树状数组)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2758 题意:平面上有n个多边形(凸包和圆).任意两个多边形AB只有两种关系:(1) ...
- 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 ...
随机推荐
- 数据结构和算法 – 6.构建字典: DictionaryBase 类和 SortedList 类
6.1.DictionaryBase 类的基础方法和属性 大家可以把字典数据结构看成是一种计算机化的词典.要查找的词就是关键字,而词的定义就是值. DictionaryBase 类是一种用作专有字 ...
- Arch Linux 安装、配置、美化和优化
国庆假期玩了下Arch Linux,发现这货跟Ubuntu之流相差甚远,甚难调教,而且安裝过程全命令行,会有各种问题,各种知识... --- 安装引导器--- -------------------- ...
- 【Java EE 学习 21 下】【使用java实现邮件发送、邮件验证】
一.邮件发送 1.邮件发送使用SMTP协议或者IMAP协议,这里使用SMTP协议演示. SMTP协议使用的端口号:25 rfc821详细记载了该协议的相关信息 (1)使用telnet发送邮件(使用12 ...
- 无废话ExtJs 入门教程十四[文本编辑器:Editor]
无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功 ...
- 使用python递归子目录处理日志文件
重要说明: (1)python使用4个空格进行层次缩进的(不是tab),在eclipse里面可以直接使用tab缩进,是因为eclipse会实时地将tab转成4个空格 (2)在eclipse中安装pyD ...
- 攻城狮在路上(贰) Spring(三)--- Spring 资源访问利器Resource接口
Spring为了更好的满足各种底层资源的访问需求.设计了一个Resource接口,提供了更强的访问底层资源的能力.Spring框架使用Resource装载各种资源,包括配置文件资源.国际化属性文件资源 ...
- PHP二维数组去除重复,重复值相加
$arr = array( array('id' => 122, 'name' => '张三', 'amount' => '1'), array('id' => 123, 'n ...
- QQ互联OAuth
/** * QQ互联 oauth * @author dyllen * */ class Oauth { //取Authorization Code Url const PC_CODE_URL = ' ...
- SOA 架构中的ESB是更好的应用于异构系统集成整合还是用于统一服务调用/基础服务实施
一.讨论主题与观点 写一篇文章.发现一次自觉得有意思的SOA架构方面的讨论,源于昨天AgileEAS.NET SOA 平台群(113723486)里几个群友的一次关于ESB的一次讨论. 大家的讨论观点 ...
- hdu 3032 sg打表找规律 *
有n堆石子,alice先取,每次可以选择拿走一堆石子中的1~x(该堆石子总数) ,也可以选择将这堆石子分成任意的两堆.alice与bob轮流取,取走最后一个石子的人胜利. 打表代码: #include ...