zoukankan      html  css  js  c++  java
  • ztz11的noip模拟赛T1:愤怒的XiaoX

    链接:

    https://www.luogu.org/problemnew/show/U47231

    思路:

    这道题其实就是一道双Lazy线段树裸题

    因为我们知道,当k一定时,取反偶数次最后k位等于不取反

    同理,当k一定时,翻转偶数次最后k位等于不取反

    我们使用双Lazy分别存下这两个东西

    同时一直对2取模

    同时我们使用标记永久化

    向下传参Lazy

    单点查询到这个点时,判断是否需要取反即可

    取反和翻转是位运算基本知识

    大家可以看代码

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define rij register int j
    #define rii register int i
    #define rs 65536
    using namespace std;
    struct tree{
        int fz,qf,val;
    }x[250005];
    int n,k,q,t,bs[50];
    void ycl()
    {
        bs[0]=1;
        for(rii=1;i<=25;i++)
        {
            bs[i]=bs[i-1]*2;
        }
    }
    void cf(int val)
    {
        unsigned int kkk=val;
        while(kkk!=0)
        {
            cout<<kkk%2<<" ";
            kkk/=2;
        }
        cout<<endl;
    }
    int qf(int val)
    {
        int bs=(1<<k);
        int ltt=val%bs;
        val-=ltt;
        ltt=-ltt;
        ltt--;
        unsigned kkk=ltt;
        kkk%=bs;
        return val+kkk;
    }
    int fz(int val)
    {
        int bis=(1<<k);
        int ltt=val%bis;
        int v=0;
        val-=ltt;
        for(rii=1;i<=k;i++)
        {
            v+=(ltt%2)*bs[k-i];
            ltt/=2;
        }
        return val+v;
    }
    void add(int wz,int nl,int nr,int val,int bh)
    {
        if(wz==nl&&wz==nr)
        {
            x[bh].val=val;
            return;
        }
        int mid=(nl+nr)/2;
        if(wz<=mid)
        {
            add(wz,nl,mid,val,bh*2);
        }
        else
        {
            add(wz,mid+1,nr,val,bh*2+1);
        }
    }
    void change1(int l,int r,int nl,int nr,int bh)
    {
        if(l<nl)
        {
            l=nl;
        }
        if(r>nr)
        {
            r=nr;
        }
        if(l==nl&&r==nr)
        {
            x[bh].qf++;
            x[bh].qf%=2;
            return;
        }
        int mid=(nl+nr)/2;
        if(l<=mid)
        {
            change1(l,r,nl,mid,bh*2);
        }
        if(r>mid)
        {
            change1(l,r,mid+1,nr,bh*2+1);
        }
    }
    void change2(int l,int r,int nl,int nr,int bh)
    {
        if(l<nl)
        {
            l=nl;
        }
        if(r>nr)
        {
            r=nr;
        }
        if(l==nl&&r==nr)
        {
            x[bh].fz++;
            x[bh].fz%=2;
            return;
        }
        int mid=(nl+nr)/2;
        if(l<=mid)
        {
            change2(l,r,nl,mid,bh*2);
        }
        if(r>mid)
        {
            change2(l,r,mid+1,nr,bh*2+1);
        }
    }
    int query(int wz,int nl,int nr,int bh,int lazy1,int lazy2)
    {
        lazy1%=2;
        lazy2%=2;
        if(wz==nl&&wz==nr)
        {
            lazy1+=x[bh].qf;
            lazy2+=x[bh].fz;
            int ltt=x[bh].val;
            if(lazy1==1)
            {
                ltt=qf(ltt);
            }
            if(lazy2==1)
            {
                ltt=fz(ltt);
            }
            return ltt;
        }
        int mid=(nl+nr)/2;
        if(wz<=mid)
        {
            return query(wz,nl,mid,bh*2,lazy1+x[bh].qf,lazy2+x[bh].fz);
        }
        else
        {
            return query(wz,mid+1,nr,bh*2+1,lazy1+x[bh].qf,lazy2+x[bh].fz);
        }
    }
    void pd(int wz,int l,int r)
    {
        if(l==r)
        {
            if(x[wz].fz!=0)
            {
                x[wz].fz=0;
                x[wz].val=fz(x[wz].val);
            }
            if(x[wz].qf!=0)
            {
                x[wz].qf=0;
                x[wz].val=qf(x[wz].val);
            }
            return;
        }
        if(x[wz].fz!=0)
        {
            x[wz*2].fz++;
            x[wz*2].fz%=2;
            x[wz*2+1].fz++;
            x[wz*2+1].fz%=2;
        }
        if(x[wz].qf!=0)
        {
            x[wz*2].qf++;
            x[wz*2].qf%=2;
            x[wz*2+1].qf++;
            x[wz*2+1].qf%=2;
        }
        x[wz].qf=0;
        x[wz].fz=0;
        int mid=(l+r)/2;
        pd(wz*2,l,mid);
        pd(wz*2+1,mid+1,r);
    }
    int main()
    {
    //     freopen("XiaoX10.in","r",stdin);
    //     freopen("XiaoX10.out","w",stdout);
        ycl();
        scanf("%d%d",&n,&t);
        for(rii=1;i<=n;i++)
        {
            int val;
            scanf("%d",&val);
            add(i,1,rs,val,1);
        }
        for(rii=1;i<=t;i++)
        {
            if(i!=1)
            {
                pd(1,1,rs);
            }
            scanf("%d%d",&q,&k);
            int pid,l,r,wz;
            for(rij=1;j<=q;j++)
            {
                scanf("%d",&pid);
                if(pid==1)
                {
                    scanf("%d%d",&l,&r);
                    change1(l,r,1,rs,1);
                }
                if(pid==2)
                {
                    scanf("%d%d",&l,&r);
                    change2(l,r,1,rs,1);
                }
                if(pid==3)
                {
                    scanf("%d",&wz);
                    int ltt=query(wz,1,rs,1,0,0);
                    printf("%d
    ",ltt);
                }
            }
        }
        k=4;
    }
  • 相关阅读:
    【BZOJ1396】识别子串
    【BZOJ3309】DZY Loves Math
    【XSY3306】alpha
    整体二分
    常系数齐次线性递推
    【XSY2968】线性代数
    【XSY2892】【GDSOI2018】谁是冠军
    【BZOJ5020】[LOJ2289]【THUWC2017】在美妙的数学王国中畅游
    【XSY2989】字符串
    【XSY2988】取石子
  • 原文地址:https://www.cnblogs.com/ztz11/p/9877927.html
Copyright © 2011-2022 走看看