zoukankan      html  css  js  c++  java
  • [BZOJ2758] [SCOI2012]Blinker的噩梦 扫描线+set

    题目大意:有n个圆或凸多边形,这些图形不会相交,每当走入或走出一个图形时需要异或上一个代价,有m组操作:

    询问操作,每次询问从一个点走到另一个点时,需要的代价(初始代价为0)

    修改操作,每次修改一个图形的代价

    数据范围:n≤1e5,点权的绝对值不大于1e9

    此题真实毒瘤题

    考虑到此题图形之间两两互不相交,那么图形与图形之间的关系为相离或包含,包含关系我们可以将其建成一棵树结构。

    我们用set来维护一个以x为第一关键字的扫描线,每次扫描到一个新的图形,我们就将该图形拆成上下两部分(可以理解为左右括号),分别加入到set中(考虑到图形不会包含,那么在图形出现的值域内,如果只考虑当前加入的这些图形,这些图形构成的括号序列是不会发生变化的,我们只需要写一个在给定X值情况下能求出图形上下两部分的Y值的函数即可)

    然后再做一条射线往上,碰到了另一个多边形,不难发现只会有两种情况:

    第一种情况:遇到一个图形的上部分,那么显然碰到的那个图形包含了当前图形。

    第二种情况:遇到一个图形的下部分,那么显然当前图形与碰到的图形是相离关系。

    当某个图形在扫描线变化后不再出现时,从set中删去这个图形。

    (以上说得有点玄乎,感性理解下吧)

    我们基于这些关系,建出了一棵树。

    对于一个查询操作,显然是查询从树上一个点到另一个点的异或和,考虑到这个值可能会被修改,用树状数组随便维护下就好了

    然后就没了,说起来很简单写起来hhh。

    注意精度损失!!!!!

      1 #include<bits/stdc++.h>
      2 #define M 300005
      3 #define INF 1e15
      4 #define eps 1e-9
      5 #define D long double
      6 #define sqr(x) ((x)*(x))
      7 #define lowbit(x) ((x)&(-x))
      8 using namespace std; 
      9 
     10 int b[M]={0},N,val[M]={0}; 
     11 void updata(int x,int k){ for(int i=x;i<=N;i+=lowbit(i)) b[i]^=k;}
     12 int query(int x){ int k=0; for(int i=x;i;i-=lowbit(i)) k^=b[i]; return k;}
     13 
     14 struct edge{int u,next;}e[M]={0}; int head[M]={0},use=0;
     15 void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
     16 int dfn[M]={0},low[M]={0},fa[M]={0},t=0;
     17 void dfs(int x){
     18     dfn[x]=++t; 
     19     for(int i=head[x];i;i=e[i].next) dfs(e[i].u);
     20     low[x]=t;
     21     updata(dfn[x],val[x]);
     22     updata(low[x]+1,val[x]);
     23 }
     24 
     25 D nowX;
     26 
     27 struct node{
     28     int n,down,val,id; 
     29     D X,Y,r,x[37],y[37];
     30     D lx,rx;
     31     void makebig(){X=Y=0; r=INF;lx=-INF; rx=INF;}
     32     void rd(int ID){
     33         id=ID;
     34         char op[10]; scanf("%s",op);
     35         if(op[0]=='C'){
     36             n=0; scanf("%Lf%Lf%Lf",&X,&Y,&r);
     37             lx=X-r; rx=X+r;
     38         }else{
     39             scanf("%d",&n);
     40             lx=INF; rx=-INF;
     41             for(int i=1;i<=n;i++){
     42                 scanf("%Lf%Lf",x+i,y+i);
     43                 lx=min(lx,x[i]);
     44                 rx=max(rx,x[i]);
     45             }
     46             x[n+1]=x[1]; y[n+1]=y[1];
     47         }
     48         scanf("%d",&val);
     49     }
     50     void rd(){
     51         n=-1;
     52         scanf("%Lf%Lf",&X,&Y);
     53         lx=rx=X;
     54     }
     55     D get(D now){
     56         D Y1=INF,Y2=-INF;
     57         if(n==-1) return Y;
     58         if(n==0){
     59             Y1=Y-sqrt(max(sqr(r)-sqr(X-now),(D)0.0));
     60             Y2=Y+sqrt(max(sqr(r)-sqr(X-now),(D)0.0));
     61         }else{
     62             for(int i=1;i<=n;i++){
     63                 D now1=x[i],now2=x[i+1];
     64                 if(now1==now2) continue;
     65                 if(now1>now2) swap(now1,now2);
     66                 if(!(now1-eps<=now&&now<=now2+eps)) continue;
     67                 D k=(y[i+1]-y[i])/(x[i+1]-x[i]);
     68                 D nowy=y[i]+(now-x[i])*k;
     69                 Y1=min(Y1,nowy);
     70                 Y2=max(Y2,nowy);
     71             }
     72         }
     73         if(down) return Y1;
     74         return Y2;
     75     }
     76     friend bool operator <(node a,node b){
     77         D vala=a.get(nowX);
     78         D valb=b.get(nowX);
     79         if(fabs(vala-valb)>eps) return vala<valb;
     80         return a.down>b.down;
     81     }
     82 }a[M]; 
     83 set<node> s;
     84 int n,m,q; 
     85 
     86 void pushset(node now){
     87     now.down=0; s.insert(now);
     88     now.down=1; s.insert(now);
     89 }
     90 void popset(node now){
     91     now.down=0; s.erase(now);
     92     now.down=1; s.erase(now);
     93 }
     94 
     95 struct hh{
     96     int id,zf; hh(int ID=0,int ZF=0){id=ID; zf=ZF;}
     97     friend bool operator <(hh x,hh y){
     98         D valx,valy;
     99         if(x.zf==-1) valx=a[x.id].lx; else valx=a[x.id].rx;
    100         if(y.zf==-1) valy=a[y.id].lx; else valy=a[y.id].rx;
    101         return valx<valy;
    102     }
    103 }p[M*3]={0};
    104 
    105 int pointsum=0;
    106 int chx[M]={0},chval[M]={0},id1[M]={0},id2[M]={0};
    107 
    108 int main(){
    109 //    freopen("in.txt","r",stdin);
    110 //    freopen("out.txt","w",stdout);
    111     a[0].makebig(); fa[0]=-1;
    112     nowX=-INF; pushset(a[0]);
    113     scanf("%d%d",&n,&q);
    114     for(int i=1;i<=n;i++) a[++pointsum].rd(i);
    115     
    116     for(int i=1;i<=n;i++) val[i]=a[i].val;
    117     for(int i=1;i<=n;i++) p[++m]=hh(i,1),p[++m]=hh(i,-1);
    118     
    119     for(int i=1;i<=q;i++){
    120         char op[10]; scanf("%s",op);
    121         if(op[0]=='C'){scanf("%d%d",chx+i,chval+i);}
    122         else{
    123             a[++pointsum].rd();
    124             p[++m]=hh(pointsum,0);
    125             id1[i]=pointsum;
    126             
    127             a[++pointsum].rd();
    128             p[++m]=hh(pointsum,0);
    129             id2[i]=pointsum;
    130         }
    131     }
    132     
    133     sort(p+1,p+m+1);
    134     N=m+1;
    135     for(int x=1;x<=m;x++){
    136         int id=p[x].id;
    137         //cout<<s.size()<<endl;
    138         if(p[x].zf==-1) nowX=a[id].lx; else nowX=a[id].rx;
    139         if(p[x].zf==-1||p[x].zf==0){
    140             pushset(a[id]);
    141             set<node>::iterator it=s.find(a[id]); it++;
    142             if(it->down) 
    143             fa[id]=fa[it->id];
    144             else fa[id]=it->id;
    145             
    146             if(p[x].zf==0) 
    147             popset(a[id]);
    148         }else{
    149             popset(a[id]);
    150         }
    151     }
    152     for(int i=1;i<=m;i++) add(fa[i],i);
    153     dfs(0);
    154     int ans=0; 
    155     for(int i=1;i<=q;i++){
    156     //    if(chx[i]) continue;
    157         if(chx[i]){
    158             int x=chx[i],zhi=chval[i];
    159             updata(dfn[x],val[x]);
    160             updata(low[x]+1,val[x]);
    161             val[x]=zhi;
    162             updata(dfn[x],val[x]);
    163             updata(low[x]+1,val[x]);
    164         }else{
    165             int ans1=query(dfn[id1[i]]);
    166             int ans2=query(dfn[id2[i]]);
    167             ans=ans^ans1^ans2;
    168             printf("%d
    ",ans);
    169         }
    170     }
    171 //    return 0;
    172 }
  • 相关阅读:
    【Java EE 学习 81】【CXF框架】【CXF整合Spring】
    【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
    【Java EE 学习 80 上】【WebService】
    【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】
    【Java EE 学习 79 上】【mybatis 基本使用方法】
    【Java EE 学习 78 下】【数据采集系统第十天】【数据采集系统完成】
    【Java EE 学习 78 中】【数据采集系统第十天】【Spring远程调用】
    【Java EE 学习 78 上】【数据采集系统第十天】【Service使用Spring缓存模块】
    【Java EE 学习 77 下】【数据采集系统第九天】【使用spring实现答案水平分库】【未解决问题:分库查询问题】
    【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10358489.html
Copyright © 2011-2022 走看看