4810: [Ynoi2017]由乃的玉米田
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 464 Solved: 222
[ 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
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
yumi
yuno
yuno
yumi
HINT
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 100001;
const int maxn = 1E5 + 5;
struct Query{
int l,r,op,x,key,Num; Query(){}
Query(int l,int r,int op,int x,int key,int Num):
l(l),r(r),op(op),x(x),key(key),Num(Num){};
bool operator < (const Query &B) const
{
if (key < B.key) return 1;
if (key > B.key) return 0;
return r < B.r;
}
}D[maxn];
int n,m,A[maxn],cnt[maxn];
bool Ans[maxn];
bitset <N> b1,b2;
inline void Insert(int pos)
{
++cnt[A[pos]];
if (cnt[A[pos]] == 1)
b1[A[pos]] = b2[N - 1 - A[pos]] = 1;
}
inline void Delete(int pos)
{
--cnt[A[pos]];
if (!cnt[A[pos]])
b1[A[pos]] = b2[N - 1 - A[pos]] = 0;
}
inline bool Check1(int x)
{
return (b1 & (b1 << x)).any();
}
inline bool Check2(int x)
{
return (b1 & (b2 >> (N - 1 - x))).any();
}
inline bool Check3(int x)
{
if (!x) return b1[0];
for (int i = 1; i * i <= x; i++)
{
if (x % i != 0) continue;
int a = i,b = x / i;
if (b1[a] == 1 && b1[b] == 1) return 1;
}
return 0;
}
inline int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret * 10 + ch - '0',ch = getchar();
return ret;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
freopen("test.txt","w",stdout);
#endif
n = getint(); m = getint(); int Sqrt = sqrt(n);
for (int i = 1; i <= n; i++) A[i] = getint();
for (int i = 1; i <= m; i++)
{
int op,l,r,x;
op = getint(); l = getint();
r = getint(); x = getint();
D[i] = Query(l,r,op,x,l / Sqrt,i);
}
sort(D + 1,D + m + 1);
int L = 1,R = 0;
for (int i = 1; i <= m; i++)
{
Query now = D[i];
while (R > now.r) Delete(R--);
while (R < now.r) Insert(++R);
while (L < now.l) Delete(L++);
while (L > now.l) Insert(--L);
if (now.op == 1) Ans[now.Num] = Check1(now.x);
else if (now.op == 2) Ans[now.Num] = Check2(now.x);
else Ans[now.Num] = Check3(now.x);
}
for (int i = 1; i <= m; i++)
puts(Ans[i] ? "yuno" : "yumi");
return 0;
}