BZOJ4810: [Ynoi2017]由乃的玉米田

4810: [Ynoi2017]由乃的玉米田

Time Limit: 30 Sec  Memory Limit: 256 MB
Submit: 746  Solved: 368
[Submit][Status][Discuss]

Description

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

Input

第一行两个数n,m
后面一行n个数表示ai
后面m行每行四个数opt l r x
opt表示这个是第几种操作,l,r表示操作的区间,x表示这次操作的x
定义c为每次的x和ai中的最大值,ai >= 0,每次的x>=2n,m,c <= 100000

Output

对于每个询问,如果可以,输出yuno,否则输出yumi

Sample Input

5 5
1 1 2 3 4
2 1 1 2
1 1 2 2
3 1 1 1
3 5 5 16
1 2 3 4

Sample Output

yuno
yumi
yuno
yuno
yumi

HINT

Source

 
【题解】
莫队 + bitset神奇的维护
若[l,r]内有i,则bitset[i] = 1
对于操作1:a - b = d ,等价于a = b + d,即将bitset左移d位(整体加d),与原bitset取并(与运算)即可
对于操作2:a + b = d,等价于(MAXN - )a = (MAXN - d) + b,维护bitset2,若有i则bitset2[MAXN - i] = 1,
之后同操作1
对于操作3:a * b = d,对d暴力分解因数即可
全是操作三复杂度可达n^2
但却能过。。
第一道莫队
细节:  关于区间变换的处理,先扩张,然后减小,少判断一些,用data存有多少个,不能单纯的改0或1
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <bitset>
  7 #include <algorithm>
  8 #define min(a, b) ((a) < (b) ? (a) : (b))
  9 #define max(a, b) ((a) > (b) ? (a) : (b))
 10 
 11 inline void swap(int &x, int &y)
 12 {
 13     int tmp = x;x = y;y = tmp;
 14 }
 15 
 16 inline void read(int &x)
 17 {
 18     x = 0;char ch = getchar(), c = ch;
 19     while(ch < '0' || ch > '9')c = ch, ch = getchar();
 20     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
 21     if(c == '-')x = -x;
 22 }
 23 
 24 const int INF = 0x3f3f3f3f;
 25 const int MAXN = 100001;
 26 const int MAXNUM = 100001;
 27 
 28 int n,m,num[MAXN + 10],l[MAXN + 10],r[MAXN + 10],block,size,ans[MAXN + 10],cnt[MAXN + 10],data1[MAXN + MAXN],data2[MAXN + MAXN];
 29 
 30 std::bitset<MAXNUM + MAXNUM> b1,b2;
 31 
 32 struct Node
 33 {
 34     int l, r, kuai, id, d;
 35     Node(int _l, int _r, int _kuai, int _id, int _d){d = _d;id = _id;l = _l;r = _r;kuai = _kuai;}
 36     Node(){}
 37 }node[MAXN << 1];
 38 
 39 bool cmp(int a, int b)
 40 {
 41     return node[a].kuai == node[b].kuai ? node[a].r < node[b].r : node[a].kuai < node[b].kuai;
 42 }
 43 
 44 int tiaoshi;
 45 
 46 int main()
 47 {
 48     read(n);read(m);
 49     for(register int i = 1;i <= n;++ i)
 50         read(num[i]);
 51     size = sqrt(n);
 52     block = n/size;
 53     if(block * size < n)++ block;
 54     for(register int i = 1;i <= block;++ i)
 55         l[i] = (i - 1) * block + 1, r[i] = min(i * block, n);
 56     for(register int i = 1;i <= m;++ i)
 57     {
 58         read(node[i].id), read(node[i].l), read(node[i].r);read(node[i].d);
 59         node[i].kuai = (node[i].l - 1)/size + 1;
 60         cnt[i] = i;
 61     }
 62     std::sort(cnt + 1, cnt + 1 + m, cmp);
 63     int now = 0, l = 1, r = n;
 64     for(register int j = l;j <= r;++ j)
 65         ++ data1[num[j]], ++ data2[MAXN - num[j]], b1[num[j]] = 1, b2[MAXN - num[j]] = 1;
 66     for(register int p = 1;p <= m;++ p)
 67     {
 68         register int i = cnt[p];
 69         while(node[i].l > l)
 70         {
 71             -- data1[num[l]], -- data2[MAXN - num[l]];
 72             if(!data1[num[l]])
 73                 b1[num[l]] = 0;
 74             if(!data2[MAXN - num[l]])
 75                 b2[MAXN - num[l]] = 0;
 76             ++ l;
 77         }
 78         while(node[i].r < r)
 79         {
 80             -- data1[(num[r])], -- data2[MAXN - num[r]];
 81             if(!data1[num[r]])
 82                 b1[num[r]] = 0;
 83             if(!data2[MAXN - num[r]])
 84                 b2[MAXN - num[r]] = 0;
 85             -- r;
 86         }
 87         while(node[i].l < l)
 88         {
 89             -- l, ++ data1[num[l]], ++ data2[MAXN - num[l]]; 
 90             if(data1[num[l]] > 0)
 91                 b1[num[l]] = 1; 
 92             if(data2[MAXN - num[l]] > 0)
 93                 b2[MAXN - num[l]] = 1;
 94         }
 95         while(node[i].r > r)
 96         {
 97             ++ r, ++ data1[num[r]], ++ data2[MAXN - num[r]];
 98             if(data1[num[r]] > 0)
 99                 b1[num[r]] = 1; 
100             if(data2[MAXN - num[r]] > 0)
101                 b2[MAXN - num[r]] = 1;
102         }
103         if(node[i].id == 1)
104         {
105             if(((b1 >> node[i].d) & b1).any())
106                 ans[i] = 1;
107         }
108         else if(node[i].id == 2)
109         {
110             if(((b1 << (MAXN - node[i].d)) & b2).any())
111                 ans[i] = 1;
112         }
113         else
114         {
115             int tmp = sqrt(node[i].d);
116             if(node[i].d == 0)
117             {
118                 if(b1.test(0))
119                     ans[i] = 1;
120                 continue;
121             }
122             for(register int j = 1;j <= tmp;++ j)
123             {
124                 if(node[i].d % j == 0)
125                 {
126                     if(b1.test(j) && b1.test(node[i].d/j))
127                     {
128                         ans[i] = 1;
129                         break;
130                     }
131                 }
132             }
133         }
134     }
135     for(register int i = 1;i <= m;++ i)
136         if(ans[i])
137             printf("yuno\n");
138         else
139             printf("yumi\n");
140     return 0;
141 }
BZOJ4810

 

posted @ 2017-10-13 00:21  嘒彼小星  阅读(192)  评论(0编辑  收藏  举报