bzoj 4810: [Ynoi2017]由乃的玉米田 莫队 bitset
bitset大概就是让你轻松建立一个很长的二进制数来存东西,并提供了快捷的操作和优美的常数。
#include <bitset>
bitset <32> b;32为长度 需要引用头文件,定义一个bitset。
stl的东西,所以从0开始。 支持左右移。 支持下标访问修改。
b.any() | b中是否存在置为1的二进制位 |
b.none() | b中不存在置为1的二进制位 |
b.count() | b中置为1的二进制位的个数 |
b.size() | b中二进制位的个数 |
b[pos] | 访问b中在pos处的二进制位 |
b.test(pos) | b中在pos处的二进制位是否为1 |
b.set() | 把b中所有二进制位都置为1 |
b.set(pos) | 把b中在pos处的二进制位置为1 |
b.reset() | 把b中所有二进制位都置为0 |
b.reset(pos) | 把b中在pos处的二进制位置为0 |
b.flip() | 把b中所有二进制位逐位取反 |
b.flip(pos) | 把b中在pos处的二进制位取反 |
b.to_ulong() | 用b中同样的二进制位返回一个unsigned long值 |
大概bitset就这样子。。。 然后这道题我们莫队一下,维护bitset记录每种数值是否出现过,并维护cnt来维护数量。然后我们对于乘。直接从cnt内尝试暴力枚举因数即可。对于减,我们考虑把bitset右移x位,然后与原bitset&一下,看有没有1。 对于加我们可以有如下变形。 a[i] + a[j] = x a[i] = x - a[j] a[i] = (x - c) + (c - a[j]) a[i] - (c - a[j]) = (x-c) 这是不是与减 a[i] - a[j] = x 很类似。再维护一个bitset就可以了。
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <algorithm> 5 #include <bitset> 6 using namespace std; 7 int n,m,wid; 8 struct dat 9 { 10 int opt,l,r,x,id; 11 }; 12 bool operator < (const dat &x,const dat &y) 13 { 14 if (x.l / wid != y.l / wid) return x.l / wid < y.l / wid; 15 return x.r < y.r; 16 } 17 bitset <110000> f,g; 18 dat rec[110000]; 19 int a[110000],cnt[110000]; 20 bool res[110000]; 21 int main() 22 { 23 scanf("%d%d",&n,&m); 24 wid = int(sqrt(n)); 25 for (int i = 1;i <= n;i++) scanf("%d",&a[i]); 26 for (int i = 1;i <= m;i++) 27 scanf("%d%d%d%d",&rec[i].opt,&rec[i].l,&rec[i].r,&rec[i].x),rec[i].id= i; 28 sort(rec + 1,rec + m + 1); 29 int l = 0,r = 0; 30 for (int i = 1;i <= m;i++) 31 { 32 while (l > rec[i].l) 33 { 34 cnt[a[--l]]++; 35 f[a[l]] = 1; 36 g[100000 - a[l]] = 1; 37 } 38 while (r < rec[i].r) 39 { 40 cnt[a[++r]]++; 41 f[a[r]] = 1; 42 g[100000 - a[r]] = 1; 43 } 44 while (l < rec[i].l) 45 { 46 cnt[a[l]]--; 47 if (!cnt[a[l]]) f[a[l]] = 0,g[100000 - a[l]] = 0; 48 l++; 49 } 50 while (r > rec[i].r) 51 { 52 cnt[a[r]]--; 53 if (!cnt[a[r]]) f[a[r]] = 0,g[100000 - a[r]] = 0; 54 r--; 55 } 56 if (rec[i].opt == 1) 57 { 58 if (!((f >> rec[i].x) & f).any()) res[rec[i].id] = 0;else 59 res[rec[i].id] = 1; 60 }else 61 if (rec[i].opt == 2) 62 { 63 if (!((g >> (100000 - rec[i].x)) & f).any()) res[rec[i].id] = 0;else 64 res[rec[i].id] = 1; 65 }else 66 { 67 for (int j = 1;j * j <= rec[i].x;j++) 68 { 69 if (rec[i].x % j == 0 && f[j] == 1 && f[rec[i].x / j] == 1) {res[rec[i].id] = 1;break;} 70 } 71 if (rec[i].x == 0 && f[0]) {res[rec[i].id] = 1;}; 72 } 73 } 74 for (int i = 1;i <= m;i++) puts(res[i] ? "yuno":"yumi"); 75 return 0; 76 } 77
心之所动 且就随缘去吧