【bzoj4810】【ynoi2018】由乃的玉米田
4810: [Ynoi2017]由乃的玉米田
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 1090 Solved: 524
[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
题解:
//对于bitset来说,空间大一倍一意味着时间打一倍;
//所以能小尽量小,(感谢bzoj的老爷机让我发现了这一点)
对于一个区间,
bitset维护x和最大值-x,可以通过左移和右移查询x+y和x-y
根号枚举因子可以查询x*y;
多个区间由于空间问题所以使用莫队优化空间,时间要付出一个根号;
//注意bitset右移长度为负数的话似乎会出事。。。。。。
$O(M\sqrt{M} + \frac{CM}{64} )$
20181101
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<cmath> 7 #include<vector> 8 #include<stack> 9 #include<map> 10 #include<bitset> 11 #define il inline 12 #define rg register 13 #define Run(i,l,r) for(rg int i=l;i<=r;i++) 14 #define Don(i,l,r) for(rg int i=l;i>=r;i--) 15 #define ll long long 16 #define ld long double 17 #define inf 0x3f3f3f3f 18 using namespace std; 19 const int N=100010 ;//, mx=100000; 20 il char gc(){ 21 static char*p1,*p2,s[1000000]; 22 if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin); 23 return(p1==p2)?EOF:*p1++; 24 } 25 il int rd(){ 26 int x=0; char c=gc(); 27 while(c<'0'||c>'9')c=gc(); 28 while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc(); 29 return x; 30 } 31 int n,m,a[N],num[N],ans[N],bl[N],mx; 32 struct data{ 33 int l,r,op,x; int id; 34 il bool operator <(const data&A)const{ 35 return bl[l]==bl[A.l]?r<A.r:l<A.l; 36 } 37 }Q[N]; 38 bitset<N>f1,f2; 39 il void upd(int x,int y){ 40 if(!num[x]&&y==1)f1.set(x),f2.set(mx-x);//f1[x]=f2[mx-x]=1; 41 num[x]+=y; 42 if(!num[x]&&y==-1)f1.reset(x),f2.reset(mx-x);//f1[x]=f2[mx-x]=0; 43 } 44 il bool ask(int op,int x){ 45 if(op==1){ 46 return ((f1>>x)&f1).count(); 47 }else if(op==2){ 48 return (f1&(f2>>(mx-x))).count(); 49 }else { 50 for(int i=1;i*i<=x;i++){ 51 if(x%i==0&&f1.test(i)&&f1.test(x/i)){ 52 return true; 53 } 54 } 55 return false; 56 } 57 } 58 int main(){ 59 freopen("in.in","r",stdin); 60 freopen("out.out","w",stdout); 61 n=rd(); m=rd(); 62 int u=2*sqrt(n+0.5); 63 Run(i,1,n)a[i]=rd(),bl[i]=i/u+1,mx=max(mx,a[i]); 64 Run(i,1,m){ 65 Q[i].op=rd(); Q[i].l=rd(); Q[i].r=rd(); Q[i].x=rd(); Q[i].id=i; 66 mx = max(Q[i].x,mx); 67 } 68 sort(Q+1,Q+m+1); 69 for(rg int i=1,l=1,r=0;i<=m;i++){ 70 while(l>Q[i].l)upd(a[--l],1); 71 while(r<Q[i].r)upd(a[++r],1); 72 while(l<Q[i].l)upd(a[l++],-1); 73 while(r>Q[i].r)upd(a[r--],-1); 74 ans[Q[i].id] = ask(Q[i].op,Q[i].x); 75 } 76 for(rg int i=1;i<=m;i++){ 77 puts(ans[i]?"yuno":"yumi"); 78 } 79 return 0; 80 }//by tkys_Austin;