【题解】洛谷P3674、P5355: 小清新人渣的本愿和 [Ynoi2017] 由乃的玉米田
P3674 小清新人渣的本愿
自己想出来了,好耶!!其实和兔子洞那题差不多,标记哪些数区间中出现了,因为 bitset 就相当于状压,也是支持位运算的,所以减法相当于右移 \(x\) 位后与运算,如果有交说明可以得到 \(x\),加法就要额外维护 \(g=f_{N-i}\),查询时直接查找 \(f\) 与 \(g\) 右移 \(N-x\) 位是否有交,乘法更简单直接分解因数就可以,这样的复杂度位 \(O(m(\sqrt{n}+\frac{n}{w}))\)。
\(a+b=x,b=x-a\),所以维护加要进行减操作。
其实不随机的话可以是 \(O(\frac{n^2}{w}\sqrt{n})\),这样是乘法拉满的情况,但是数据范围没这么出就不管了。
#include <bits/stdc++.h> #define int long long #define ls p<<1 #define rs p<<1|1 #define re register #define pir pair<int,int> const int N=1e5+10,M=25005; const int mod=1e8; using namespace std; int n,m; int a[N]; int of[N],len; bitset<N> f,g; int cnt[N]; struct ss{ int l,r,op,id,x; }q[N]; void add(int x){ cnt[a[x]]++; if(cnt[a[x]]==1){ f[a[x]]=1; g[N-a[x]]=1; } } void del(int x){ if(cnt[a[x]]==1){ f[a[x]]=0; g[N-a[x]]=0; } cnt[a[x]]--; } int ans[N]; bool cmp(ss g,ss h){ return (of[g.l]^of[h.l])?of[g.l]<of[h.l]:(of[g.l]&1)?of[g.r]<of[h.r]:of[g.r]>of[h.r]; } signed main(){ // freopen("xp1.in","r",stdin); ios::sync_with_stdio(false); cin.tie(nullptr); cin>>n>>m; len=sqrt(n); for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=m;i++){ int op,l,r,x; cin>>op>>l>>r>>x; q[i].id=i;q[i].l=l;q[i].r=r;q[i].op=op;q[i].x=x; of[i]=(i-1)/len+1; } sort(q+1,q+m+1,cmp); int l=1,r=0; for(int i=1;i<=m;i++){ int ql=q[i].l,qr=q[i].r,id=q[i].id,x=q[i].x,op=q[i].op; while(l>ql) add(--l); while(r<qr) add(++r); while(l<ql) del(l++); while(r>qr) del(r--); int flag=0; if(op==1){ if((f&(f>>x)).any()){ flag=1; } } else if(op==2){ if((f&(g>>(N-x))).any()){ flag=1; } } else{ for(int j=1;j*j<=x;j++){ if(x%j==0&&f[j]==1){ if(f[x/j]==1){ flag=1; break; } } } } ans[id]=flag; } for(int i=1;i<=m;i++){ if(ans[i]){ cout<<"hana"; } else{ cout<<"bi"; } cout<<"\n"; } return 0; }
P5355 [Ynoi2017] 由乃的玉米田
然后就是升级版,增添了除法操作。
分类讨论,对于 \(x> \sqrt{N}\) 的部分通过枚举除数来判断是否有合法的被除数,复杂度 \(O(\sqrt{n})\)。
对于 \(x\le \sqrt{N}\) 同一处理,p从1到n遍历序列,\(las_i\) 表示 \(i\) 数字上一次出现的最后的位置,\(mx_i\) 表示 \(i\) 位置满足在 \([l,p]\) 同时出现 \(y\) 和 \(xy\),或同时存在 \(y\) 和 \(\frac{y}{x}\) 靠右的位置,每扫到一个点都更新 \(mx\)。
查询时判断当前 \(x\) 的 \(mx_r\ge l\)。
我们每次枚举复杂度为 \(O(n)\),一共有 \(\sqrt{n}\) 个数,所以处理这些数的总复杂度为 \(O(n\sqrt{n})\)。
#include <bits/stdc++.h> #define int long long #define ls p<<1 #define rs p<<1|1 #define re register #define pir pair<int,int> const int N=1e5+10,M=25005; const int mod=1e8; using namespace std; int n,m; int a[N]; int of[N],len; bitset<N> f,g; int cnt[N]; struct ss{ int l,r,op,id,x; }q[N]; void add(int x){ cnt[a[x]]++; if(cnt[a[x]]==1){ f[a[x]]=1; g[N-a[x]]=1; } } void del(int x){ if(cnt[a[x]]==1){ f[a[x]]=0; g[N-a[x]]=0; } cnt[a[x]]--; } int ans[N]; bool cmp(ss g,ss h){ return (of[g.l]^of[h.l])?of[g.l]<of[h.l]:(of[g.l]&1)?of[g.r]<of[h.r]:of[g.r]>of[h.r]; } struct sa{ int l,r,id; }; vector<sa> v[N]; int las[N]; int res[N]; int mx[N]; void solve(){ for(int i=1;i<=350;i++){ if(v[i].empty()){ continue; } memset(mx,0,sizeof mx); memset(las,0,sizeof las); int l=0; for(int j=1;j<=n;j++){ las[a[j]]=j; if(i*a[j]<=N){ l=max(l,las[i*a[j]]); } if(a[j]%i==0){ l=max(l,las[a[j]/i]); } mx[j]=l; } for(sa j:v[i]){ ans[j.id]=(j.l<=mx[j.r]); } } } signed main(){ // freopen("xp1.in","r",stdin); ios::sync_with_stdio(false); cin.tie(nullptr); cin>>n>>m; len=sqrt(n); for(int i=1;i<=n;i++){ cin>>a[i]; of[i]=(i-1)/len+1; } int cntq=0; for(int i=1;i<=m;i++){ int op,l,r,x; cin>>op>>l>>r>>x; if(op==4&&x<=350){ v[x].push_back({l,r,i}); } else{ cntq++; q[cntq].id=i;q[cntq].l=l;q[cntq].r=r;q[cntq].op=op;q[cntq].x=x; } } sort(q+1,q+cntq+1,cmp); int l=1,r=0; for(int i=1;i<=cntq;i++){ int ql=q[i].l,qr=q[i].r,id=q[i].id,x=q[i].x,op=q[i].op; while(l>ql) add(--l); while(r<qr) add(++r); while(l<ql) del(l++); while(r>qr) del(r--); int flag=0; if(op==1){ if((f&(f>>x)).any()){ flag=1; } } else if(op==2){ if((f&(g>>(N-x))).any()){ flag=1; } } else if(op==3){ for(int j=1;j*j<=x;j++){ if(x%j==0&&f[j]==1&&f[x/j]==1){ flag=1; break; } } } else{ for(int j=1;j*x<=N;j++){ if(f[j]&&f[x*j]){ flag=1; break; } } } ans[id]=flag; } solve(); for(int i=1;i<=m;i++){ if(ans[i]){ cout<<"yuno"; } else{ cout<<"yumi"; } cout<<"\n"; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」