1 条题解
-
0
自动搬运
来自洛谷,原作者为

EnofTaiPeople
MGXS搬运于
2025-08-24 22:56:25,当前版本为作者最后更新于2024-03-25 09:12:57,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
需要我来讲一下铜组该怎么通过吗?
对于一次 的查询,考虑将 和 表示出来,如果能很方便的查询当前的运算值,这道题就能做了。
由于先进行与运算,所以我们可以想象一下将若干用与运算连接的数并在一起,用一个
std::vector存起来,其中两个数之间的运算符都是或。如果
vector的大小很大,复杂度就会变得很劣质,但我们发现当vector的大小超过 时,可以将中间的所有数字或起来合并。于是暴力处理前后缀的
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
- 上传者