P3674 小清新人渣的本愿
P3674 小清新人渣的本愿
题目背景
本题时限3s,空间128MB
我感觉我要挂省选
人渣的本愿是一个有趣的番
可爱的花火喜欢从小和她谈♂笑♂风♂生的欧♂尼♂酱鸣海,欧尼酱特别想当老师,然后剧本安排当了花火的班主任。
然而有个叫做皆川茜的奇怪的人抢走了欧尼酱!
花火就很失落呀,然后看到一个叫做麦的人也很失落,原来麦喜欢茜老师。。。
花火和麦从此天天谈笑风生,然后决定在一起,把对方当做自己喜欢的人的替代品
因为花火很可爱,所以有许多奇怪的人喜欢花火,比如一个叫做绘鸠早苗的妹子
因为麦长的也不错,所以有许多奇怪的人喜欢麦,比如一个叫做最可的妹子
然后就开始愉快的生♂活了~
以上内容如果你没有看过这个番可以无视掉
按照套路,现在欧尼酱会问花火一个OI问题(一般是数据结构),然后花火肯定不会OI,所以会来请教您这位IOI Au选手,然后您肯定会帮助她
但是
这个套路太无聊了,我们来换一个(但是不会改变您是IOI Au选手的事实)
花火有一天看了几个有趣的番,叫做“在W??身上寻找女装是否搞错了什么”,“从女装开始的?X?”,“我家大佬不可能那么可爱”,然后发现??H太厉害了,然后就穿越到了异世界,和???谈笑风生
花火就和???做了一个交♂易,花火帮???做一道题,然后???帮花火改写地球online的程序,让花火和欧尼酱在♂一♂起
???虽然非常厉害,但是不会数据结构题,他最近刚刚遇到一道有趣的数据结构题,于是他接受了交易
但是花火也不会数据结构题呀
所以又回到了这个老套路,就靠您这个IOI Au选手来帮她了!
以上内容如果你没有看过这个番还是可以无视掉
这里用一个经典的图来解释这个关系(其实没那么蛋疼的)

题目描述
这个题是这样的:
给你一个序列 \(a\),长度为 \(n\),有 \(m\) 次操作,每次询问一个区间是否可以选出两个数它们的差为 \(x\),或者询问一个区间是否可以选出两个数它们的和为 \(x\),或者询问一个区间是否可以选出两个数它们的乘积为 \(x\) ,这三个操作分别为操作 \(1,2,3\)。
选出的这两个数可以是同一个位置的数。

输入格式
第一行两个数 \(n,m\)。
后面一行 \(n\) 个数表示 \(a_i\)。
后面 \(m\) 行每行四个数 opt l r x。
\(opt\) 表示这个是第几种操作,\(l,r\) 表示操作的区间,\(x\) 表示这次操作的 \(x\)。
输出格式
对于每个询问,如果可以,输出 hana,否则输出 bi。
说明/提示
对于 \(100\%\) 的数据,\(n,m,c \leq 10^5\)。

Solution:
bitset 好题,lxl哥哥是好人%%%
先解决前两问:
我们使用一个 bitset \(f\) 来维护一个数字在当前区间上是否出现过。
对于 \(a-b=x:\)
- 对于任意的 \(a\),只要 \(a,a-x\) 在 \(f\) 中同时出现,即 $ f \text{ and } f \text{ << } x \ne 0$ 那么这个询问的答案就是 ture,否则是 falase.
对于 \(a+b=x:\)
我们维护另一个 bitset \(g\),用来表示 \(f\) 的翻转。\(f_i\) 对应了 \(g_{N-i}\)。这样一来,我们在 \(f\) 上找a,在 \(g\) 上找 \(b\),则有:
\(a-(N-b)=x-N\)
类似的,只要满足 \((f \text{ and }(g \text{ >> } (N-q[i].x))\ne 0\) 这个询问的答案就是 ture,否则是 falase.
然后是看起来很难,其实很简单的第三问。我们发现值域是 \(10^5\) 级别的,所以我们完全可以 \(O(\sqrt c)\) 枚举 \(x\) 的因子 \(d\) ,查询 \(d,\frac{x}{d}\) 是否同时存在就好了。
时间复杂度 \(O(\frac{n^2}{w})\),然后这题就做完了。
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int inf=1e5;
#define _(x) (inf-x)
bitset<N> f,g,ans;
int n,m,len,cnt;
int bl[N],a[N],t[N];
void build()
{
len=sqrt(n);cnt=n/len;
cnt+=(n%len!=1);
for(int i=1;i<=n;i++)
{
bl[i]=(i-1)/len+1;
}
}
struct task{
int opt,l,r,x,id;
bool operator <(const task &t)const{
return bl[l]==bl[t.l] ? (bl[l]&1 ? r<t.r : t.r<r) : l<t.l;
}
}q[N];
void add(int x)
{
t[x]++;
if(t[x]==1)f[x]=g[_(x)]=1;
}
void del(int x)
{
t[x]--;
if(!t[x])f[x]=g[_(x)]=0;
}
void work()
{
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&q[i].opt,&q[i].l,&q[i].r,&q[i].x);q[i].id=i;
}
sort(q+1,q+1+m);
int l=1,r=0;
for(int i=1;i<=m;i++)
{
while(l<q[i].l)del(a[l++]);
while(q[i].l<l)add(a[--l]);
while(r<q[i].r)add(a[++r]);
while(q[i].r<r)del(a[r--]);
if(q[i].opt==1)
{
ans[q[i].id]=((f&(f<<q[i].x)).any());
}
if(q[i].opt==2)
{
ans[q[i].id]=((f&(g>>_(q[i].x))).any());
}
if(q[i].opt==3)
{
int lim=sqrt(q[i].x);
for(int d=1;d<=lim;d++)if(q[i].x%d==0)
{
if(f[d]&f[q[i].x/d]){ans[q[i].id]=1;break;}
}
}
}
for(int i=1;i<=m;i++)printf(ans[i] ? "hana\n" : "bi\n");
}
int main()
{
//freopen("P3674.in","r",stdin);
//freopen("P3674.out","w",stdout);
work();
return 0;
}

浙公网安备 33010602011771号