比赛 2024暑期C班集训1 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 水母序列 最终得分 100
用户昵称 darkMoon 运行时间 10.710 s
代码语言 C++ 内存使用 48.54 MiB
提交时间 2024-07-01 10:59:54
显示代码纯文本
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define mp make_pair
using namespace std;
ifstream fin("Jelly.in");
ofstream fout("Jelly.out");
auto mread = [](){
    int x;
    fin >> x;
    return x;
};
const int N = 1e5 + 5, M = 1048580;
int n = mread(), m = mread(), a[N], ans[M], f[25][N], s[N * 5], lzk[N * 5], lzc[N * 5];
vector<pair<int, int> > v[N];
bool e[M];
vector<int> p;
void add2(int x, int nl, int nr, int l, int r, int k, int c){
    int fi = k + (nl - l) * c, la = k + (nr - l) * c;
    s[x] += (fi + la) * (nr - nl + 1) / 2;
    lzk[x] += fi, lzc[x] += c;
    return;
}
void pushdown(int x, int nl, int nr){
    if(lzk[x] == 0 && lzc[x] == 0)
    return;
    int mid = nl + nr >> 1;
    add2(x << 1, nl, mid, nl, nr, lzk[x], lzc[x]);
    add2(x << 1 | 1, mid + 1, nr, nl, nr, lzk[x], lzc[x]);
    lzk[x] = lzc[x] = 0;
    return;
}
void pushup(int x){
    s[x] = s[x << 1] + s[x << 1 | 1];
}
void add(int x, int nl, int nr, int l, int r, int k, int c){
//    printf("--- %lld %lld %lld %lld %lld %lld %lld\n", x, nl, nr, l, r, k, c);
    if(nl >= l && nr <= r){
        add2(x, nl, nr, l, r, k, c);
        return;
    }
    pushdown(x, nl, nr);
    int mid = nl + nr >> 1;
    if(mid >= l)
    add(x << 1, nl, mid, l, r, k, c);
    if(mid + 1 <= r)
    add(x << 1 | 1, mid + 1, nr, l, r, k, c);
    pushup(x);
    return;
}
int query(int x, int nl, int nr, int p){
    if(nl == nr)
    return s[x];
    pushdown(x, nl, nr);
    int mid = nl + nr >> 1;
    int ans;
    if(p <= mid)
    ans = query(x << 1, nl, mid, p);
    else
    ans = query(x << 1 | 1, mid + 1, nr, p);
    pushup(x);
    return ans;
}
int makeOr(int l, int r){
    int lg = __lg(r - l + 1);
    return f[lg][l] | f[lg][r - (1 << lg) + 1];
}
void cg(int now, int x){
    int l = 1, r = now;
    while(l < r){
        int mid = l + r >> 1;
        if((makeOr(mid, now) | x) == x)
        r = mid;
        else
        l = mid + 1;
    }
//    if(now > 95000)
//    printf("*** %lld %lld %lld %lld\n", l, now, x, makeOr(l, now));
    if(e[x] == 0){
        add(1, 1, n, l, now, now - l + 1, -1);
//        printf("*** %lld %lld %lld %lld\n", l, now, now - l + 1, -1ll);
        if(l > 1){
            add(1, 1, n, 1, l - 1, now - l + 1, 0);
//            printf("*** %lld %lld %lld %lld\n", 1ll, l - 1, now - l + 1, 0ll);
        }
//        for(int j = 1; j <= n; j ++)
//        printf("%lld ", query(1, 1, m, j));
//        printf("\n");
    }
    if(l > 1)
    cg(l - 1, x | a[l - 1]);
    return;
}
signed main(){
    e[0] = e[1] = 1;
    for(int i = 2; i < M; i ++){
        if(e[i] == 0){
            p.push_back(i);
        }
        for(int j = 0; j < p.size(); j ++){
            if(p[j] * i >= M)
            break;
            e[p[j] * i] = 1;
            if(i % p[j] == 0)
            break;
        }
    }
    for(int i = 1; i <= n; i ++)
    f[0][i] = a[i] = mread();
    for(int j = 1; j <= 20; j ++){
        for(int i = 1; i <= n - (1 << j) + 1; i ++)
        f[j][i] = f[j - 1][i] | f[j - 1][i + (1 << j - 1)];
    }
    for(int i = 1; i <= m; i ++){
        int l = mread(), r = mread();
        v[r].push_back(mp(l, i));
    }
    for(int i = 1; i <= n; i ++){
//        if(i > 95000)
//        printf("*** %lld\n", i);
        cg(i, a[i]);
//        for(int j = 1; j <= n; j ++)
//        printf("%lld ", query(1, 1, m, j));
//        printf("\n");
        for(auto t : v[i]){
            ans[t.se] = query(1, 1, n, t.fi);
//            printf("*** %lld %lld %lld\n", t.fi, i, query(1, 1, n, t.fi));
        }
    }
    for(int i = 1; i <= m; i ++)
    fout << ans[i] << "\n";
//    printf("%lld\n", ans[i]);
    return 0;
}