【题解】洛谷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;
}
posted @   sad_lin  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示