luogu3674 小清新人渣的本愿 (bitset+莫队)

对于加减,用bitset维护当前每个数有没有

对于乘,暴力枚举约数

然后莫队

复杂度$O(m(\sqrt{n}+\frac{c}{64}))$

 1 #include<bits/stdc++.h>
 2 #define pa pair<ll,ll>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 #define MP make_pair
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn=1e5+10;
 8
 9 inline char gc(){
10     return getchar();
11     static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf;
12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++;
13 }
14 inline ll rd(){
15     ll x=0;char c=gc();bool neg=0;
16     while(c<‘0‘||c>‘9‘){if(c==‘-‘) neg=1;c=gc();}
17     while(c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+c-‘0‘,c=gc();
18     return neg?(~x+1):x;
19 }
20
21 int N,V,NN,M,v[maxn];
22 struct Node{
23     int o,l,r,x,i;
24 }q[maxn];
25 bool ans[maxn];
26 int cnt[maxn];
27 bitset<100005> b1,b2;
28
29 inline bool cmp(Node a,Node b){
30     return a.l/NN==b.l/NN?((a.l/NN)&1?a.r<b.r:a.r>b.r):a.l<b.l;
31 }
32
33 inline void solve(int p,int d){
34     if(!cnt[v[p]]) b1[v[p]]=1,b2[V-v[p]]=1;
35     cnt[v[p]]+=d;
36     if(!cnt[v[p]]) b1[v[p]]=0,b2[V-v[p]]=0;
37 }
38
39 int main(){
40     //freopen("","r",stdin);
41     int i,j,k;
42     N=rd(),NN=sqrt(N),M=rd();
43     for(i=1;i<=N;i++) v[i]=rd(),V=max(V,v[i]);
44     for(i=1;i<=M;i++){
45         q[i].o=rd(),q[i].l=rd(),q[i].r=rd(),q[i].x=rd(),q[i].i=i;
46     }sort(q+1,q+M+1,cmp);
47     int l=1,r=0;
48     for(i=1;i<=M;i++){
49         while(r<q[i].r) solve(++r,1);
50         while(r>q[i].r) solve(r--,-1);
51         while(l<q[i].l) solve(l++,-1);
52         while(l>q[i].l) solve(--l,1);
53         if(q[i].o==1){
54             ans[q[i].i]=(b1&(b1<<q[i].x)).count();
55         }else if(q[i].o==2){
56             ans[q[i].i]=(b1&(q[i].x>V?(b2<<(q[i].x-V)):(b2>>(V-q[i].x)))).count();
57         }else{
58             for(j=1;j*j<=q[i].x;j++){
59                 if(q[i].x%j==0&&b1[j]&&b1[q[i].x/j]){
60                     ans[q[i].i]=1;break;
61                 }
62             }
63         }
64     }
65     for(i=1;i<=M;i++){
66         if(ans[i]) printf("hana\n");
67         else printf("bi\n");
68     }
69     return 0;
70 }

原文地址:https://www.cnblogs.com/Ressed/p/10028430.html

时间: 2024-10-12 08:25:34

luogu3674 小清新人渣的本愿 (bitset+莫队)的相关文章

洛谷 P3674 小清新人渣的本愿 [莫队 bitset]

传送门 题意: 给你一个序列a,长度为n,有Q次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ,这三个操作分别为操作1,2,3 题面太强啦!!! 感觉就是莫队,想了一下分块不好搞更坚定了莫队的信念 $a-b=x$,$a=x+b$,放在权值数组上就是b右移x位,$bitset$大法好 加法同理 乘法,总共就$\sqrt{N}$个约数.... #include <iostream> #incl

LuoguP3674 小清新人渣的本愿

题目地址 题目链接 题解 这种lxl的题还是没修改操作的题基本就是莫队 分开考虑每个询问 1.减法 \(a-b=x?a=b+x\) 用一个\(bitset\),第\(i\)位表示有没有\(i\)这个数 那么查询其实就等价于查询bit&(bit>>x)之后里面有没有1 \(a+b=x\) 2.加法 \(a+b=x\) 设\(p=n-b\) \(a-p=a-n+b=x-n\) 维护一下另外一个\(bitset\),里面存的是\(n-i\)有没有出现过 查询直接查bit1&(bit2

【题解】Luogu P3674 小清新人渣的本愿

原题传送门 这题还算简单(我记得我刚学oi时就来写这题,然后暴力都爆零了) 看见无修改,那么这题应该是莫队 维护两个bitset,第二个是第一个的反串,bitset内维护每个数字是否出现过 第一种操作: 要求y-z=x,所以y=z+x 最后判断有没有k和k-x都出现在bitset中的情况 第二种操作: 和第一种类似的方法,就不再讲了qwqwq 第三种操作: 暴力把x分解成两个数的乘积,判断这两个数是否出现过 因为莫队是\(O(n \sqrt n)\)的·,所以这里也不需要更快 #include

bzoj 4810 由乃的玉米田 - bitset - 莫队算法

由乃在自己的农田边散步,她突然发现田里的一排玉米非常的不美.这排玉米一共有N株,它们的高度参差不齐. 由乃认为玉米田不美,所以她决定出个数据结构题 这个题是这样的: 给你一个序列a,长度为n,有m次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是 否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ,这三个操作分别为操作1 ,2,3选出的这两个数可以是同一个位置的数 Input 第一行两个数n,m 后面一行n个数表示ai 后面m行每行四个数op

BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题&amp;&amp;学习笔记】

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 9894  Solved: 4561[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两

BZOJ 2038 2009国家集训队 小Z的袜子【模板&#183;莫队】

[题解] 1,先说说莫队算法. 莫队算法是用来离线处理区间问题的算法.非常易于理解和使用,且运用十分广泛. 假设我们现在已知区间[L,R]的答案,如果我们能以较低的时间复杂度扩展得到区间$[L-1,R],[L+1,R],[L,R-1],[L,R+1]$的答案,我们就可以使用莫队算法.通常可以接受的扩展的时间复杂度为$O(1)$或者$O(logN)$. 那么莫队算法具体是怎样的呢?首先我们把询问按照区间左端点分成$\sqrt{n}$块,同一块内按照区间右端点进行排序.当我们按调整后的顺序处理询问时

luogu P4688 [Ynoi2016]掉进兔子洞 bitset 莫队

题目链接 luogu P4688 [Ynoi2016]掉进兔子洞 题解 莫队维护bitset区间交个数 代码 // luogu-judger-enable-o2 #include<cmath> #include<bitset> #include<cstdio> #include<cstring> #include<algorithm> inline int read() { int x = 0,f = 1; char c = getchar();

_bzoj2038 [2009国家集训队]小Z的袜子(hose)【莫队】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 裸的莫队,注意要先移动右端点再移动左端点. #include <cstdio> #include <algorithm> #include <cmath> const int maxn = 50005, maxm = 50005; int n, m, c[maxn], s[maxn], l, r, siz; long long fenzi[maxm], fe

BZOJ2038 [2009国家集训队]小Z的袜子(hose)(莫队算法)

神奇的莫队算法,用来解决可离线无修改的区间查询问题: 首先对原序列进行分块,√n块每块√n个: 然后对所有查询的区间[l,r]进行排序,首先按l所在的块序号升序排序,如果一样就按r升序排序: 最后就按顺序一个一个求出各个查询的结果:知道[l,r]的答案,并且在此基础上能在比较快地在O(x)得到相邻区间[l+1,r].[l-1,r].[l,r-1].[l,r+1]的答案,那样就能从[l,r]的基础上对lr加加减减得到任意一个区间[l',r']的答案. 看似暴力,但这样做的时间复杂度是O(x*n*√