炸了 0分
查看原帖
炸了 0分
1284632
coding2024楼主2024/8/5 14:56
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<map>
#include<bitset>
using namespace std;

const int N = 1e5 + 10;
int n, m, s, a[N];
bool ans[N];
map<int, int>cnt;
bitset<N> st1, st2;
struct Q {
    int op, l, r, x, k;
    bool operator<(const Q& c)const
    {
        if (l / s != c.l / s)return l / s < c.l / s;
        if (l / s & 1)return r < c.r;
        return r > c.r;
    }
}q[N];

void add(int i)
{
    cnt[a[i]]++;
    st1[a[i]] = st2[N - a[i] - 1] = 1;
}

void del(int i)
{
    cnt[a[i]]--;
    if (!cnt[a[i]])st1[a[i]] = st2[N - a[i] - 1] = 0;
}

int main() {
    scanf("%d%d", &n, &m);
    s = sqrt(n);

    for (int i = 1; i <= n; i++)scanf("%d", &a[i]);

    for (int i = 1; i <= m; i++)
    {
        scanf("%d%d%d%d", &q[i].op, &q[i].l, &q[i].r, &q[i].x);
        q[i].k = i;
    }
    sort(q + 1, q + m + 1);

    int l = 1, r = 0;
    for (int i = 1; i <= m; i++)
    {
        int ll = q[i].l, rr = q[i].r, op = q[i].op, x = q[i].x;
        while (l < ll)del(l++);
        while (r < rr)add(++r);
        while (l > ll)add(--l);
        while (r > rr)del(r--);

        bool& res = ans[q[i].k];
        if (op == 1)res = (st1 & (st1 << x)).any();
        else if (op == 2)res = (st1 & (st2 >> (N - x - 1))).any();   //st2:反向位集
        else {
            for (int j = 1; j <= x / j; j++){
                if(x%j!=0) continue;  //注意跳过,x/j是下取整
                if(st1[j] && st1[x / j])
                {
                    res=1;
                    break;
                }
            }
        }
    }

    for (int i = 1; i <= m; i++)
        if (ans[i])puts("hana");
        else puts("bi");

    return 0;
}
2024/8/5 14:56
加载中...