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 

原文地址:https://www.cnblogs.com/iat14/p/12216549.html

时间: 2024-10-13 02:48:25

bzoj 4810: [Ynoi2017]由乃的玉米田 莫队 bitset的相关文章

[BZOJ]4810: [Ynoi2017]由乃的玉米田

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

bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化

3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 314  Solved: 132[Submit][Status] Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美.这排玉米一共有N株,它们的高度参差不齐.方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列.方伯伯可以选择一个区间,把这个区间的

BZOJ 3594[Scoi2014]方伯伯的玉米田

题面: 3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1403  Solved: 630[Submit][Status][Discuss] Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美.这排玉米一共有N株,它们的高度参差不齐.方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列.方伯伯可

BZOJ4810 [Ynoi2017]由乃的玉米田

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! 题目链接:BZOJ4810 正解:$bitset$+莫队算法 解题报告: 考虑直接上$bitset$会$MLE$,我们用莫队来优化空间,不用每个点都开一个. 维护一个$cnt$数组,表示每种值的出现次数,那么我可以用$bitset$维护每种权值是否出现过.

BZOJ 2038 小Z的袜子(hose) (莫队离线)

题目地址:BZOJ 2038 裸的莫队算法. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> #includ

bzoj 3594 [Scoi2014]方伯伯的玉米田(DP+二维BIT)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3594 [题意] 给定一个n个数的序列,有K次将一个区间内的数加1的机会,问最长不下降子序列. [思路] 首先知道每次加1一个区间为[i,n]肯定不会差. 设f[i][j]为前i个数,还有j次机会的LIS,则有转移式: f[i][j] = max{ f[a][b],h[a]+b<=h[i]+j } 则可以用二维BIT加速方程转移. [代码] 1 #include<set> 2

BZOJ 3594 [Scoi2014]方伯伯的玉米田(二维树状数组)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3594 [题目大意] 给出一个数列,选出k个区间使得区间内数全部加1, 求k次操作之后最长的不下降子序列 [题解] 我们发现,每次的区间右端点一定贪心选到最右端才是最优的, 那么在用树状数组统计的时候,只要一个点被+1了,那么后面的点起码+1, 我们在树状数组后面加一维统计被区间包含的次数,发现也是前缀和关系, 所以用二维树状数组统计答案即可. 为避免自身被重复统计,第二维循环降序.

BZOJ 3594 Scoi2014 方伯伯的玉米田 树状数组

题目大意:给定一个序列,可以选择k次区间并将区间内每个数都+1,求操作之后LIS的最大值 我的做法不是标解...5E的复杂度为何跑的飞起... 首先一个显而易见的结论就是我们选择的k次区间右端点都是n时才能保证最优 知道这个我们就可以DP了- - 令f[i][j]表示前i个数上升j次的最大LIS 那么有f[i][j]=max{f[k][l]|k<i,l<=j,a[k]+l<=a[i]+j}+1 看到三维偏序就可以用二维树状数组了- - 时间复杂度O(nklog(max(ai)+k)log

Luogu P5355 [Ynoi2017]由乃的玉米田

Link 开一个桶记录每个数字出现过多少次,同时用bitset维护\(x\)是否出现过. 那么查询是否有两个数的差为\(x\)就是把bitset右移\(x\)位然后与自己,如果有位置为\(1\)那么就说明存在. 查询是否有两个数的和为\(x\)也可以类似地做,多开一个bitset维护\(10^5-x\)是否出现过. 查询是否有两个数的积为\(x\)可以直接枚举因数查询,注意特判\(x=0\)的情况. 最后是查询是否有两个数的商为\(x\),首先特判\(x=0\)的情况,对于\(x\ge64\)的