c++
查看原帖
c++
365628
惜云银月楼主2020/9/17 19:14
#include<bits/stdc++.h>
#define ld double
using namespace std;
const int N=100010;
const ld inf=1e20,eps=1e-9;
int n,m,cnt,tot,o=1,hd[N],f[N],st[N],ed[N],idx,c[N],rt,ch[N<<1][2],fa[N<<1],bl[N<<1];
ld X; 
struct Edge{int v,nt;}E[N<<1];
char s[10];
struct P{
    ld x,y;
    P(ld _x=0,ld _y=0):x(_x),y(_y){};
    bool operator <(const P&a)const{return x==a.x?y<a.y:x<a.x;}
}q[N<<1];
struct line{ld x;int id,typ;}B[N<<2];
struct Graph{
    int typ,w;
    int n;P p[35];
    P O;ld R;
    void init(){
        scanf("%s",s+1);
        typ=s[1]=='P';
        if(!typ)scanf("%lf%lf%lf%d",&O.x,&O.y,&R,&w);
        else{
            scanf("%d",&n);
            for(int j=0;j<n;++j)scanf("%lf%lf",&p[j].x,&p[j].y);
            scanf("%d",&w);
            p[n]=p[0];
        }
    }
    ld getl(){
        if(!typ)return O.x-R;
        ld re=inf;
        for(int i=0;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=0;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=0;i<n;++i){
            ld A=p[i].x,B=p[i].y,C=p[i+1].x,D=p[i+1].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=0;i<n;++i){
            ld A=p[i].x,B=p[i].y,C=p[i+1].x,D=p[i+1].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<<1|1))return 1;
    if(k==(n<<1))return 0;    
    ld t=k&1?A[k>>1].cal1(X):A[k>>1].cal0(X);
    return t<y;
}
bool cmp2(int x,int y){
    if(x==(n<<1|1))return 1;
    if(x==(n<<1))return 0;    
    if((x^y)==1)return x&1;
    ld t1=x&1?A[x>>1].cal1(X):A[x>>1].cal0(X),
       t2=y&1?A[y>>1].cal1(X):A[y>>1].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][1]==y]=x;else k=x;
    int l=ch[y][1]==x,r=l^1;
    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][1]==y)^(ch[y][1]==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=0;
    while(k){
        if(cmp1(k,y))re=k,k=ch[k][1];
        else k=ch[k][0];
    }return re;
}
void add(int x){
    /*if(x==20193){
        puts("haha");
    }*/
    int p=x<<1,q=p|1;
    ins(rt,p);ins(rt,q);
    splay(q,rt);
    int t=ch[q][0];
    while(ch[t][1])t=ch[t][1];
    adde(t&1?t>>1:f[t>>1],x);
    splay(t,rt);
}
void del(int x){
    splay(x,rt);
    int y=ch[x][0];
    while(ch[y][1])y=ch[y][1];
    splay(y,ch[x][0]);
    ch[y][1]=ch[x][1];
    fa[ch[x][1]]=y;
    fa[rt=y]=0;
}
void getp(int x){
    int t=find(q[x].y);
    bl[x]=t&1?t>>1:f[t>>1];
    splay(t,rt);
} 
void mfy(int x,int y){for(;x<=n;x+=x&-x)c[x]^=y;}
int ask(int x){int re=0;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]+1,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]+1,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=1;i<=n;++i){
        A[i].init();
        B[++cnt]=(line){A[i].getl(),i,1};
        B[++cnt]=(line){A[i].getr(),i,-1};
    } 
    for(int i=1;i<=m;++i){
        scanf("%s",s+1);
        C[i].typ=s[1]=='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,0};
            C[i].v=++tot,scanf("%lf%lf",&q[tot].x,&q[tot].y);
            B[++cnt]=(line){q[tot].x,tot,0};
        }
    }
    sort(B+1,B+cnt+1,cmpB);
    ++n;
    ch[rt=n<<1][0]=n<<1|1;
    fa[n<<1|1]=n<<1;
    for(int i=1;i<=cnt;++i){
        X=B[i].x;
        if(B[i].typ==1)add(B[i].id);
        else if(B[i].typ==-1)del(B[i].id<<1),del(B[i].id<<1|1);
        else getp(B[i].id);
    }
    dfs(n);
    int ans=0;
    for(int i=1;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 0;
}
2020/9/17 19:14
加载中...