社区讨论
悬赏5r求调线段树
P5142区间方差参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lvivn1i0
- 此快照首次捕获于
- 2024/04/28 09:53 2 年前
- 此快照最后确认于
- 2024/04/28 10:18 2 年前
CPP
#include <bits/stdc++.h>
using namespace std;
#define ios_close ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
#define yes puts("Yes")
#define no puts("No")
#define lowbit(x) (x) & (-x)
#define inf 0x3f3f3f3f
#define endl "\n"
#define PII pair<int, int>
typedef long long LL;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
int n, m;
LL a[N];
/*====================*/
struct MatrixValu
{
LL M[3][2];
MatrixValu()
{
memset(M, 0, sizeof M);
}
friend MatrixValu operator + (const MatrixValu& a, const MatrixValu& b)
{
MatrixValu c;
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 1; j++)
c.M[i][j] = (a.M[i][j] % MOD + b.M[i][j] % MOD) % MOD;
return c;
}
};
struct Tree
{
int l, r;
MatrixValu valu;
} tree[N << 2];
int ls(int p) { return p << 1; }
int rs(int p) { return p << 1 | 1; }
void PushUp(int p)
{
tree[p].valu = tree[ls(p)].valu + tree[rs(p)].valu;
}
void Build(int p, int l, int r)
{
tree[p].l = l; tree[p].r = r;
if (tree[p].l == tree[p].r)
{
tree[p].valu.M[1][1] = a[l] % MOD;
tree[p].valu.M[2][1] = ((a[l] % MOD) * (a[l] % MOD)) % MOD;
}
else
{
int mid = (tree[p].l + tree[p].r) >> 1;
Build(ls(p), l, mid + 0);
Build(rs(p), mid + 1, r);
PushUp(p);
}
}
void Change(int p, int x, int k)
{
if (tree[p].l == tree[p].r)
{
tree[p].valu.M[1][1] = k % MOD;
tree[p].valu.M[2][1] = ((k % MOD) * (k % MOD)) % MOD;
}
else
{
int mid = (tree[p].l + tree[p].r) >> 1;
if (x <= mid)Change(ls(p), x, k);
if (x > mid) Change(rs(p), x, k);
PushUp(p);
}
}
LL Ask(int p, int l, int r, bool f)
{
if (l <= tree[p].l && tree[p].r <= r)
{
return f ? tree[p].valu.M[1][1] % MOD : tree[p].valu.M[2][1] % MOD; // 1: 区间和 0: 平方和
}
else
{
LL res = 0;
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid)(res += Ask(ls(p), l, r, f) % MOD) %= MOD;
if (r > mid) (res += Ask(rs(p), l, r, f) % MOD) %= MOD;
return res % MOD;
}
}
LL qpow(int a, int b, int p)
{
if (!b) return 1;
if (b % 2 == 0)
{
LL t = qpow(a, b / 2, p) % p;
return ((t % p) * (t % p)) % p;
}
LL t = qpow(a, b - 1, p) % p;
return ((t % p) * (a % p)) % p;
}
/*====================*/
void Solve()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i]; a[i] %= MOD;
}
Build(1, 1, n);
while (m--)
{
int op, x, y;
cin >> op >> x >> y;
if (op == 1)
{
Change(1, x, y);
}
else
{
LL inv = qpow(y - x + 1, MOD - 2, MOD) % MOD;
LL res1 = Ask(1, x, y, 0) % MOD; // 平方和
LL res2 = Ask(1, x, y, 1) % MOD; // 区间和
LL ave = ((inv % MOD) * (res2 % MOD)) % MOD; // 平均数
// cout << "inv: " << inv << " res1: " << res1 << " res2: " << res2 << " ave: " << ave << endl;
LL ans = (((inv % MOD) * (res1 % MOD)) % MOD - ((ave % MOD) * (ave % MOD)) % MOD + MOD) % MOD;
cout << ans << endl;
}
}
return;
}
/*====================*/
signed main()
{
#ifndef ONLINE_JUDGE
freopen("IN.txt", "r+", stdin);
#endif
ios_close;
int _ = 1; // cin >> _;
while (_--)
Solve();
return 0;
}
wa 30pts 样例已过
回复
共 1 条回复,欢迎继续交流。
正在加载回复...