社区讨论

100 pts 但是没过

P4145上帝造题的七分钟 2 / 花神游历各国参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mlhyqg2c
此快照首次捕获于
2026/02/11 19:45
上周
此快照最后确认于
2026/02/11 20:40
上周
查看原帖
QAQ 求求了
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int BUF = 1 << 20; // 快读
char ibuf[BUF], *is = ibuf, *it = ibuf;
char obuf[BUF], *os = obuf;
inline char getch() {
    if(is == it) it = (is = ibuf) + fread(ibuf, 1, BUF, stdin);
    return is == it ? EOF : *is++;
}
inline int read() {
    int x = 0, sign = 1; char ch = getch();
    while(ch < '0' && ch != '-') ch = getch();
    if(ch == '-') {sign = -1;ch = getch();}
    do x = x * 10 + (ch ^ 48); while((ch = getch()) >= '0');
    return x * sign;
}
int n = read(), m, len = 300;
int a[100010], L[400], R[400], rec[100010]; // L是每个块的左边界,R是右边,rec是每个元素对应的块的编号
int tag[400]; //记录每个块的根号数量,如果该块 tag 数量高达 6,那么该块全部为 1
void build() {
    int pri = 0;
    for(int i = 1; i <= n; i += len) {
        L[pri] = i;
        for(int j = i; j <= n && j < i + len; j++) {
            rec[j] = pri;
        }
        R[pri] = min(n, i + len - 1);
        pri++;
    }
}
void check(int l, int r) { // 检测一个块是否全部为 1
    bool fl = 1;
    for(int i = l; i <= r; i++) {
        if(a[i] != 1) {
            return;
        }
    }
    tag[rec[l]] = 7;
}
void change(int l, int r) {
    if(rec[l] == rec[r]) { // 当在同一个块内时
        if(l == L[rec[l]] && r == R[rec[r]]) { // 当刚好覆盖一个块时
            tag[rec[l]]++;
            if(tag[rec[l]] < 6) {
                for(int i = l; i <= r; i++) {
                    a[i] = (int)sqrt(a[i]);
                }
            }
            else if(tag[rec[l]] == 6) {
                for(int i = l; i <= r; i++) a[i] = 1;
            }
            return;
        }
        for(int i = l; i <= r; i++) {
            a[i] = (int)sqrt(a[i]);
        }
        return;
    }
    if(tag[rec[l]] < 6) {
        for(int i = l; i <= R[rec[l]]; i++) {
            a[i] = (int)sqrt(a[i]);
        }
    }
    if(tag[rec[l]] < 6) {
        check(L[rec[l]], R[rec[l]]);
        if(tag[rec[l]] >= 6) {
            for(int i = L[rec[l]]; i <= R[rec[l]]; i++) a[i] = 1;
        }
    }
    if(tag[rec[r]] < 6) {
        for(int i = r; i >= L[rec[r]]; i--) {
            a[i] = (int)sqrt(a[i]);
        }
    }
    if(tag[rec[r]]) {
        check(L[rec[r]], R[rec[r]]);
        if(tag[rec[r]] >= 6) {
            for(int i = L[rec[r]]; i <= R[rec[r]]; i++) a[i] = 1;
        }
    }
    for(int i = rec[l] + 1; i < rec[r]; i++) {
        tag[i]++;
        if(tag[i] < 6) {
            for(int j = L[i]; j <= R[i]; j++) {
                a[j] = (int)sqrt(a[j]);
            }
        }
        else if(tag[i] == 6) {
            for(int j = L[i]; j <= R[i]; j++) {
                a[j] = 1;
            }
        }
    }
}
int query(int l, int r) { // 查询
    int ans = 0;
    if(rec[l] == rec[r]) {
        for(int i = l; i <= r; i++) {
            ans += a[i];
        }
        return ans;
    }
    if(tag[rec[l]] < 6) {
        for(int i = l; i <= R[rec[l]]; i++) {
            ans += a[i];
        }
    }
    else ans += (R[rec[l]] - l + 1);
    if(tag[rec[r]] < 6) {
        for(int i = r; i >= L[rec[r]]; i--) {
            ans += a[i];
        }
    }
    else ans += (r - L[rec[r]] + 1);
    for(int i = rec[l] + 1; i < rec[r]; i++) {
        if(tag[i] >= 6) {
            ans += (R[i] - L[i] + 1);
            continue;
        }
        for(int j = L[i]; j <= R[i]; j++) {
            ans += a[j];
        }
    }
    return ans;
}
signed main() {
    for(int i = 1; i <= n; i++) a[i] = read();
    m = read();
    build();
    while(m--) {
        int k = read(), l = read(), r = read();
        if(l > r) swap(l, r);
        if(k == 0) change(l, r);
        else cout <<query(l, r) <<endl;
    }
}

回复

3 条回复,欢迎继续交流。

正在加载回复...