hdu5217 segment tree

answer:

even during the exam O ( n l O g 2 n ) I haven't figured out how to do it, it's too bad... It's very simple to just ask what kind of bracket the kth position is, just use the line segment tree to maintain it directly. For the kth position in the original position, you can actually do it. Just divide the line segment tree into two. How to divide it? For each interval, after the final elimination, it must be in the form of several (plus several), then from left to right (the number is monotonically unreduced,) the same is true, then we can directly divide into two, so that O ( n l O g 2 n ) ,for O ( n l O g n ) To do this, you can take out the intervals of all the line segment trees included in the query, and then see which interval is in, and then bisect it in which interval, and that’s it.

Code:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=500010;
const int inf=2147483647;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return x*f;
}
int n,m,a[Maxn];
char s[Maxn];
struct Seg{int lc,rc,l,r,c,ll,rr;}tr[Maxn<<1];
int tot=0;
void merge(Seg &x,Seg lc,Seg rc)
{
    int t=min(lc.rr,rc.ll);
    x.c=lc.c+rc.c-2*t;
    int lll=lc.rr,rrr=rc.ll;
    lll-=t,rrr-=t;
    x.ll=lc.ll+rrr;
    x.rr=rc.rr+lll;
}
void build(int l,int r)
{
    int t=++tot;
    tr[t].l=l;tr[t].r=r;
    if(l==r)
    {
        tr[t].c=1;
        if(a[l])tr[t].ll=1,tr[t].rr=0;
        else tr[t].ll=0,tr[t].rr=1;
        return;
    }
    int mid=l+r>>1;
    tr[t].lc=tot+1,build(l,mid);
    tr[t].rc=tot+1,build(mid+1,r);
    merge(tr[t],tr[tr[t].lc],tr[tr[t].rc]);
}
void modify(int x,int p)
{
    if(tr[x].l==tr[x].r)
    {
        tr[x].ll^=1,tr[x].rr^=1;
        return;
    }
    int mid=tr[x].l+tr[x].r>>1,lc=tr[x].lc,rc=tr[x].rc;
    if(p<=mid)modify(lc,p);
    else modify(rc,p);
    merge(tr[x],tr[lc],tr[rc]);
}
int pos[Maxn],lp;
void get(int x,int l,int r)
{
    if(tr[x].l==l&&tr[x].r==r){pos[++lp]=x;return;}
    int mid=tr[x].l+tr[x].r>>1,lc=tr[x].lc,rc=tr[x].rc;
    if(r<=mid)get(lc,l,r);
    else if(l>mid)get(rc,l,r);
    else get(lc,l,mid),get(rc,mid+1,r);
}
int query1(int x,int k)
{
    if(tr[x].l==tr[x].r)return tr[x].l;
    int lc=tr[x].lc,rc=tr[x].rc;
    if(k<=tr[lc].ll)return query1(lc,k);
    else return query1(rc,k-tr[lc].ll+tr[lc].rr);
}
int query2(int x,int k)
{
    if(tr[x].l==tr[x].r)return tr[x].l;
    int lc=tr[x].lc,rc=tr[x].rc;
    if(k<=tr[rc].rr)return query2(rc,k);
    else return query2(lc,k-tr[rc].rr+tr[rc].ll);
}
int main()
{
    int T=read();
    while(T--)
    {
        tot=0;
        n=read(),m=read();
        scanf("%s",s+1);
        for(int i=1;i<=n;i++)
        {
            if(s[i]=='(')a[i]=0;
            else a[i]=1;
        }
        build(1,n);
        while(m--)
        {
            int op=read();
            int l,r,x;
            if(op==2)
            {
                l=read(),r=read(),x=read();
                lp=0;
                get(1,l,r);
                Seg tmp=tr[pos[1]];
                for(int i=2;i<=lp;i++)merge(tmp,tmp,tr[pos[i]]);
                if(x>tmp.c){puts("-1");continue;}
                if(x<=tmp.ll)
                {
                    Seg t1,t2;
                    t1.ll=t1.rr=t1.c=0;t2=t1;
                    for(int i=1;i<=lp;i++)
                    {
                        merge(t1,t1,tr[pos[i]]);
                        if(t1.ll>=x)
                        {
                            printf("%d\n",query1(pos[i],x-t2.ll+t2.rr));
                            break;
                        }
                        t2=t1;
                    }
                }
                else
                {
                    x=tmp.rr-(x-tmp.ll)+1;
                    Seg t1,t2;
                    t1.ll=t1.rr=t1.c=0;t2=t1;
                    for(int i=lp;i;i--)
                    {
                        merge(t1,tr[pos[i]],t1);
                        if(t1.rr>=x)
                        {
                            printf("%d\n",query2(pos[i],x-t2.rr+t2.ll));
                            break;
                        }
                        t2=t1;
                    }
                }
            }
            else modify(1,read());
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324598899&siteId=291194637