社区讨论
线段树2分块做法被卡常了求条
学术版参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mhiys044
- 此快照首次捕获于
- 2025/11/03 17:55 4 个月前
- 此快照最后确认于
- 2025/11/03 17:55 4 个月前
怕考场写不出来线段树,写了分块但是被卡常了。
代码是正确的,本地跑了1s左右过了。
C#include<bits/stdc++.h>
using namespace std;
int n , q , mod , mk[100005];
int a[100005];
struct node{
int l , r;
int sum;
int add , mul;
} p[100005];
inline void pushdown(int id){
if(p[id].mul != 1 || p[id].add != 0){
p[id].sum = 0;
for(int i = p[id].l ; i <= p[id].r ; i++){
a[i] = ((long long)a[i] * p[id].mul % mod + p[id].add) % mod;
p[id].sum = (p[id].sum + a[i]) % mod;
}
p[id].mul = 1;
p[id].add = 0;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> q >> mod;
for(int i = 1 ; i <= n ; i++) cin >> a[i];
int len = sqrt(n); int len2 = n / len;
for(int i = 1 ; i < len ; i++){
p[i].l = p[i - 1].r + 1;
p[i].r = i * len2;
}
p[len].l = p[len - 1].r + 1;
p[len].r = n;
for(int i = 1 ; i <= len ; i++){
p[i].sum = 0;
for(int j = p[i].l ; j <= p[i].r ; j++){
p[i].sum = (p[i].sum + a[j]) % mod;
mk[j] = i;
}
p[i].mul = 1;
p[i].add = 0;
}
while(q--){
int op , x , y , k;
cin >> op >> x >> y;
if(op <= 2){
cin >> k;
if(op == 2){
int L = mk[x] , R = mk[y];
if(L == R){
pushdown(L);
for(int i = x ; i <= y ; i++){
p[L].sum = (p[L].sum + k) % mod;
a[i] = (a[i] + k) % mod;
}
}
else{
for(int i = L + 1 ; i <= R - 1 ; i++){
p[i].add = (p[i].add + k) % mod;
p[i].sum = (p[i].sum + (long long)k * (p[i].r - p[i].l + 1)) % mod;
}
pushdown(L);
for(int i = x ; i <= p[L].r ; i++){
p[L].sum = (p[L].sum + k) % mod;
a[i] = (a[i] + k) % mod;
}
pushdown(R);
for(int i = p[R].l ; i <= y ; i++){
p[R].sum = (p[R].sum + k) % mod;
a[i] = (a[i] + k) % mod;
}
}
}
else{
int L = mk[x] , R = mk[y];
if(L == R){
pushdown(L);
for(int i = x ; i <= y ; i++){
p[L].sum = (p[L].sum + (long long)a[i] * (k - 1 + mod)) % mod;
a[i] = (long long)a[i] * k % mod;
}
}
else{
for(int i = L + 1 ; i <= R - 1 ; i++){
p[i].mul = (long long)p[i].mul * k % mod;
p[i].add = (long long)p[i].add * k % mod;
p[i].sum = (long long)p[i].sum * k % mod;
}
pushdown(L);
for(int i = x ; i <= p[L].r ; i++){
p[L].sum = (p[L].sum + (long long)a[i] * (k - 1 + mod)) % mod;
a[i] = (long long)a[i] * k % mod;
}
pushdown(R);
for(int i = p[R].l ; i <= y ; i++){
p[R].sum = (p[R].sum + (long long)a[i] * (k - 1 + mod)) % mod;
a[i] = (long long)a[i] * k % mod;
}
}
}
}
else{
int L = mk[x] , R = mk[y];
int res = 0;
if(L == R){
for(int i = x ; i <= y ; i++)
res = (res + ((long long)a[i] * p[L].mul + p[L].add)) % mod;
}
else{
for(int i = L + 1 ; i <= R - 1 ; i++)
res = (res + p[i].sum) % mod;
for(int i = x ; i <= p[L].r ; i++)
res = (res + ((long long)a[i] * p[L].mul + p[L].add)) % mod;
for(int i = p[R].l ; i <= y ; i++)
res = (res + ((long long)a[i] * p[R].mul + p[R].add)) % mod;
}
cout << res << "\n";
}
}
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...