题解:P10374 [AHOI2024 初中组] 操作
这道题其实乍一看有点麻烦:要支持区间修改,修改的不是定值,而是操作,同时这个操作区间居然还可能有嵌套?我的天哪。
那么,就很自然地想到可以开一个数组记录每个位置被操作了多少次,对于
仔细读题,观察到
发现要区间修改,可以用差分标记,又因为第
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 7;
const int mod = 10007;
int a[maxn], c[maxn], o[maxn], x[maxn], y[maxn];
int d[maxn]; // 差分数组
// 封装成函数,更方便
void add(int &x, int y) // 引用传参,这样可以同步修改x
{
x = ((x + y) % mod + mod) % mod; // 因为可能溅出负数,所以要这样写
}
void solve()
{
int n, m, k;
cin >> n >> m >> k;
for(int i = 1; i <= k; i ++){
cin >> c[i];
d[c[i]] ++, d[c[i] - 1] --; // 边输入边差分,注意倒着
}
for(int i = 1; i <= m; i ++){
cin >> o[i] >> x[i] >> y[i];
}
// 倒着跑差分,执行每一次操作
for(int i = m; i >= 1; i --){
add(d[i], d[i + 1]); // 求i位置的操作次数
if(o[i] == 1){ // 操作1,单点修改
add(a[i], y[i] * d[i]); // 注意把操作的次数d[i]乘到操作数y[i]上
}else{ // 操作2,区间修改
d[y[i]] += d[i];
d[x[i] - 1] -= d[i]; // 注意是倒着的差分
}
}
for(int i = 1; i <= n; i ++) cout << a[i] << ' ';
cout << "\n";
}
int main()
{
ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}