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 
posted @ 2020-01-20 08:38  IAT14  阅读(133)  评论(0编辑  收藏  举报