社区讨论
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 条回复,欢迎继续交流。
正在加载回复...