1 条题解

  • 0
    @ 2025-8-24 22:56:25

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar EnofTaiPeople
    MGXS

    搬运于2025-08-24 22:56:25,当前版本为作者最后更新于2024-03-25 09:12:57,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    需要我来讲一下铜组该怎么通过吗?

    对于一次 [l,r][l,r] 的查询,考虑将 [1,l)[1,l)(r,n](r,n] 表示出来,如果能很方便的查询当前的运算值,这道题就能做了。

    由于先进行与运算,所以我们可以想象一下将若干用与运算连接的数并在一起,用一个 std::vector 存起来,其中两个数之间的运算符都是或。

    如果 vector 的大小很大,复杂度就会变得很劣质,但我们发现当 vector 的大小超过 33 时,可以将中间的所有数字或起来合并。

    于是暴力处理前后缀的 vector,暴力查询即可,时空复杂度线性:

    int T,n,K,b[N];
    string s;
    struct dat{
        vector<int>a;
        void rec(){
            if(a.size()>3){
                int i,k=0;
                for(i=a.size()-2;i;--i)k|=a[i];
                a={a[0],k,a.back()};
            }
        }
        dat operator&(const dat &z){
            vector<int>res=a;
            res.back()&=z.a[0];
            int r=z.a.size(),i;
            for(i=1;i<r;++i)res.push_back(z.a[i]);
            dat rp={res};
            rp.rec();return rp;
        }
        dat operator|(const dat &z)const{
            vector<int>res=a;
            for(int p:z.a)res.push_back(p);
            dat rp={res};
            rp.rec();return rp;
        }
        int val(){
            int res=0;
            for(auto &p:a)res|=p;
            return res;
        }
    }f[N],g[N];
    int main(){
        ios::sync_with_stdio(false),cin.tie(0);
        int i,j,k,l,r,x,y,z,v1,v2;
        cin>>n>>T;
        for(x=1;x<=n;++x){
            cin>>s;
            b[x]=s[0]==(x&1?'t':'a');
        }
        f[1]={{b[1]}};
        for(x=3;x<=n;x+=2){
            if(b[x-1])f[x]=f[x-2]&(dat){{b[x]}};
            else f[x]=f[x-2]|(dat){{b[x]}};
        }
        g[n]={{b[n]}};
        for(x=n-2;x>=1;x-=2){
            if(b[x+1])g[x]=(dat){{b[x]}}&g[x+2];
            else g[x]=(dat){{b[x]}}|g[x+2];
        }
        while(T--){
            cin>>l>>r>>s;
            k=s[0]=='t';
            dat rp={{k}};
            if(l>1){
                if(b[l-1])rp=f[l-2]&rp;
                else rp=f[l-2]|rp;
            }
            if(r<n){
                if(b[r+1])rp=rp&g[r+2];
                else rp=rp|g[r+2];
            }
            putchar(rp.val()==k?'Y':'N');
        }
        return 0;
    }
    
    • 1

    信息

    ID
    9917
    时间
    2000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者