bzoj4810: [Ynoi2017]由乃的玉米田

这题带我进入了bitset的大门QwQ
在学bitset之前,我的莫队完全不知道怎么出解。。
然后去膜了几个大佬,大佬们都是用bitset
于是就补了一发。。
bitset学习
有bitset出解就好办了。。
+和-就用两个bitset就好,正着一个反着一个
然后成绩就暴力枚举就好了。。
时间复杂度据说是 O(nsqrtn+nn/32)
但其实感觉还是挺慢的,但30s的题,就凑合一下吧

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include <bitset>
using namespace std;
bitset <100010> a,b;
const int N=100005;
const int MAX=100005;
int n,m,nn;
int A[N];
int belong[N];
struct qq{int id,op,l,r,x;}s[N];
bool cmp (qq a,qq b)
{
    return belong[a.l]==belong[b.l]?a.r<b.r:belong[a.l]<belong[b.l];
}
bool ok[N];
int cnt[N];//这个数字出现了多少次 
void add (int x)
{
    cnt[x]++;
    if (cnt[x]==1) a[x]=1,b[MAX-x]=1;
}
void del (int x)
{
    cnt[x]--;
    if (cnt[x]==0) a[x]=0,b[MAX-x]=0;
}
bool cha (int x)//是否存在差为x
{
    return ((a>>x)&a).any();
}
bool he(int x)
{
    return ((b>>(MAX-x))&a).any();
}
bool Mul (int x)
{
    for (int u=1;u*u<=x;u++)
    {
        if (x%u==0&&a[u]>0&&a[x/u]>0) 
            return true;
    }
    return false;
}
int main()
{
    scanf("%d%d",&n,&m);
    nn=sqrt(n);
    for (int u=1;u<=n;u++) belong[u]=(u-1)/nn+1;
    for (int u=1;u<=n;u++)  scanf("%d",&A[u]);
    for (int u=1;u<=m;u++)
    {
        scanf("%d%d%d%d",&s[u].op,&s[u].l,&s[u].r,&s[u].x);
        s[u].id=u;
    }
    sort(s+1,s+1+m,cmp);
    memset(ok,false,sizeof(ok));
    int l=1,r=0;
    for (int u=1;u<=m;u++)
    {
        while (r<s[u].r) add(A[++r]);
        while (r>s[u].r) del(A[r--]);
        while (l<s[u].l) del(A[l++]);
        while (l>s[u].l) add(A[--l]);
        if (s[u].op==1) //差为x
            ok[s[u].id]=cha(s[u].x);
        if (s[u].op==2)
            ok[s[u].id]=he(s[u].x);
        if (s[u].op==3) 
            ok[s[u].id]=Mul(s[u].x);
    }
    for (int u=1;u<=m;u++)
        if (ok[u]) printf("yuno\n");
        else printf("yumi\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值