"Problem solution": Contact

Question A: Union

Time limit: 2 Sec   Memory Limit: 256 MB

Face questions


He declined to publicly face the question.

answer


Solution 1: + discrete segment tree.

1e18 data range out all direct discretization l and r, add a mapping array spacing can be represented.

And when the segment tree maintenance interval, the determination sweep 0 subtrees and the like is not equal to the size of the subtrees.

Maintain two markers: lazy (what will assign an interval to), xr (exclusive or whether the whole interval) run would be finished.

( I would say I'm addicted Solution Solution First, two into the water it thanks to Larry offered to explain the quality and the code )

#include<bits/stdc++.h>
#define int long long
#define rint register int
using namespace std;
int m,a[200005<<1],tot=0,cnt;
struct Tree{int l,r,sum,laz,flag;}t[200005<<3];
struct node{int l,r,val;}qu[200005];
inline void pushup(int k){t[k].sum=t[k<<1].sum+t[k<<1|1].sum;}
inline void build(int k,int l,int r)
{
    t[k].l=l,t[k].r=r,
    t[k].laz=-1,t[k].sum=0;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build(k<<1,l,mid),build(k<<1|1,mid+1,r);
}
inline void down(int k)
{
    int linl=t[k].l,linr=t[k].r,mid=(linl+linr)>>1;
    if(t[k].laz!=-1)
    {
        t[k<<1].laz=t[k<<1|1].laz=t[k].laz;
        t[k<<1].sum=t[k].laz*(mid-linl+1),t[k<<1|1].sum=t[k].laz*(linr-mid);
        t[k<<1].flag=t[k<<1|1].flag=0;t[k].laz=-1;
    }
    if(t[k].flag)
    {
        t[k<<1].flag^=1;t[k<<1|1].flag^=1;t[k].flag=0;
        t[k<<1].sum=(mid-linl+1)-t[k<<1].sum;t[k<<1|1].sum=(linr-mid)-t[k<<1|1].sum;
    }
    return ;
}
inline void change(int k,int l,int r,int val)
{
    int linl=t[k].l,linr=t[k].r;
    if(l<=linl&&linr<=r)
    {
        t[k].sum=val*(linr-linl+1);
        t[k].laz=val;t[k].flag=0;
        return ;
    }
    down(k);
    int mid=(linl+linr)>>1;
    if(l<=mid) change(k<<1,l,r,val);
    if(r>mid) change(k<<1|1,l,r,val);
    pushup(k);
}
inline void Xor(int k,int l,int r)
{
    int linl=t[k].l,linr=t[k].r;
    if(l<=linl&&linr<=r)
    {
        t[k].flag^=1;
        t[k].sum=(linr-linl+1)-t[k].sum;
        return ;
    }
    down(k);
    int mid=(linl+linr)>>1;
    if(l<=mid) Xor(k<<1,l,r);
    if(r>mid) Xor(k<<1|1,l,r);
    pushup(k);
}
inline int query(int k)
{
    int linl=t[k].l,linr=t[k].r;
    if(linl==linr) return linl;
    down(k);
    int mid=(linl+linr)>>1;
    if(t[k<<1].sum<(mid-linl+1)) return query(k<<1);
    else return query(k<<1|1);
}
signed main()
{
    scanf("%lld",&m);
    a[++tot]=1;
    for(rint i=1;i<=m;++i)
    {
        scanf("%lld %lld %lld",&qu[i].val,&qu[i].l,&qu[i].r);
        a[++tot]=qu[i].l,a[++tot]=qu[i].r+1;
    }
    sort(a+1,a+tot+1);
    cnt=unique(a+1,a+tot+1)-a-1;
    build(1,1,cnt);
    for(rint i=1;i<=m;++i)
    {
        qu[i].l=lower_bound(a+1,a+cnt+1,qu[i].l)-a;
        qu[i].r=lower_bound(a+1,a+cnt+1,qu[i].r+1)-a-1;
        if(qu[i].val==1) change(1,qu[i].l,qu[i].r,1);
        else if(qu[i].val==2) change(1,qu[i].l,qu[i].r,0);
        else Xor(1,qu[i].l,qu[i].r);
        printf("%lld\n",a[query(1)]);
    }
    return 0;
}
Segment tree Solution

Solution 2: This fear is a bare title ODT (emm some people may not know the name of this high-end atmosphere ODT, that Keduo Li tree should be known to everybody in the bar 2333)

Code inside annotated. ( A while to fill a Keduo Li tree learning notes )

(Or when you want to play God %%% alpaca game Keduo Li tree. Ed face full screen (fried) translation (library) information I really want to crash to say.)

#include<bits/stdc++.h>
#define read(A) A=init()
#define rint register int
#define ll long long
#define inf 1000000000000000000
using namespace std;
inline int init()
{
    int a=0,b=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')b=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){a=(a<<3)+(a<<1)+ch-'0';ch=getchar();}
    return a*b;
}
int m;
struct node{
    ll l,r;mutable int val;
    friend bool operator < (const node &A,const node &B){
        return A.l<B.l;
    }
};
set <node> s;
inline set<Node> :: Iterator Split (LL K) 
{ 
    SET <Node> :: = s.lower_bound IT Iterator ((Node) {K, 0 , - . 1 });
     IF (IT-> K == L) return IT ; // If the search is just a l range l, you'll get this position range of 
    IT -; // otherwise they will get a range rearward, at this time - get before the interval 
    ll linl = it-> l, LINR = IT-> R & lt, = LINV IT-> Val; // remove the current section l, R & lt, Val 
    s.erase (IT); // violent delete the current interval 
    s.insert ((node) {linl, - K- . 1 , LINV}); // the cut interval, the l-1 l is formed with the front section of the new section inserted back 
    return s.insert ((Node) {K, LINR, LINV}) First;. // returns value pair, a first dimension address 
} 
inlinevoid Change (LL L, R & lt LL, int Val) 
{ 
    SET <Node> :: = Split Iterator ITR (R & lt + . 1 ), ITL = Split (L); // first set of the endpoint taken by cutting approximately 
    s.erase (itl, ITR); // delete a set 
    s.insert ((Node) {L, R & lt, Val}); // the interval re-inserted back 
} 
inline void Xor (LL L, R & lt LL) 
{ 
    sET <Node> :: ITR = Split Iterator (R & lt + . 1 ), ITL = Split (L); // cut leftmost and rightmost interval interval 
    for ( SET <Node> :: = ITL Iterator I;! = I ITR; I ++ ) I-> Val = ^ . 1 ; // directly XOR for each interval weights 
} 
inline get_ans LL () 
{
    for(set<node>::iterator i=s.begin();i!=s.end();++i)
        if(i->val==0)return i->l;
    return (*--s.end()).r+1;
}
int main()
{
    read(m);
    s.insert((node){1,inf,0});
    for(rint i=1,ty;i<=m;++i)
    {
        ll lb,rb;read(ty);
        scanf("%lld %lld",&lb,&rb);
        if(ty==1)change(lb,rb,1);
        if(ty==2)change(lb,rb,0);
        if(ty==3)Xor(lb,rb);
        printf("%lld\n",get_ans());
    }
    return 0;
}
Keduo Li tree Solution

Guess you like

Origin www.cnblogs.com/xingmi-weiyouni/p/11610807.html