10分求调
查看原帖
10分求调
430133
liangbob楼主2023/10/1 21:57

就是 P2122 改一改,结果只有十分。

#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
const int N = 1e5 + 10;

struct node
{
    int l, r, d, p, z;
};
node t[N << 2];
int a[N];

void down(int k)
{
    if(t[k].z)
    {
        int lc = k * 2;
        int rc = k * 2 + 1;
        t[lc].z += t[k].z;
        t[lc].p += 2 * t[k].z * t[lc].d + (t[lc].r - t[lc].l + 1) * t[k].z * t[k].z;
        t[lc].d += t[k].z * (t[lc].r - t[lc].l + 1);
        t[rc].z += t[k].z;
        t[rc].p += 2 * t[k].z * t[rc].d + 1ll * (t[rc].r - t[rc].l + 1) * t[k].z * t[k].z;
        t[rc].d += t[k].z * (t[rc].r - t[rc].l + 1);
        t[k].z = 0;
    }
}

void build(int k, int l, int r)
{
    t[k].l = l;
    t[k].r = r;
    if(l == r)
    {
        t[k].d = a[l];
        t[k].p = a[l] * a[l];
        return;
    }
    int mid = (l + r) >> 1;
    int lc = k * 2;
    int rc = k * 2 + 1;
    build(lc, l, mid);
    build(rc, mid + 1, r);
    t[k].d = t[lc].d + t[rc].d;
    t[k].p = t[lc].p + t[rc].p;
}

void update(int k, int l, int r, int p)
{
    if(t[k].l == l && t[k].r == r)
    {
        t[k].z += p;
        t[k].p += 2 * p * t[k].d + 1ll * (t[k].r - t[k].l + 1) * p * p;
		t[k].d += p * (t[k].r - t[k].l + 1);
        return;
    }
    down(k);
    int mid = (t[k].l + t[k].r) / 2;
    int lc = k * 2;
    int rc = k * 2 + 1;
    if(r <= mid)
    {
        update(lc, l, r, p);    
    }
    else if(l > mid)
    {
        update(rc, l, r, p);
    }
    else
    {
        update(lc, l, mid, p);
        update(rc, mid + 1, r, p);
    } 
    t[k].d = t[lc].d + t[rc].d;
    t[k].p = t[lc].p + t[rc].p;
}

int querysum(int k, int l, int r)
{
    if(t[k].l == l && t[k].r == r)
    {
        return t[k].d;
    }
    down(k);
    int mid = (t[k].l + t[k].r) / 2;
    int lc = k * 2;
    int rc = k * 2 + 1;
    if(r <= mid)
    {
        return querysum(lc, l, r);
    }
    else if(l > mid)
    {
        return querysum(rc, l, r);
    }
    else
    {
        return querysum(lc, l, mid) + querysum(rc, mid + 1, r);
    }
}

int querysqr(int k, int l, int r)
{
    if(t[k].l == l && t[k].r == r)
    {
        return t[k].p;
    }
    down(k);
    int mid = (t[k].l + t[k].r) / 2;
    int lc = k * 2;
    int rc = k * 2 + 1;
    if(r <= mid)
    {
        return querysqr(lc, l, r);
    }
    else if(l > mid)
    {
        return querysqr(rc, l, r);
    }
    else
    {
        return querysqr(lc, l, mid) + querysqr(rc, mid + 1, r);
    }
}

const int mod = 1e9 + 7;

int qpow(int a, int b)
{
	int c = a, ans = 1;
	while(b)
	{
		if(b & 1)
		{
			ans = (ans % mod * c % mod) % mod;
		}
		c = (c * c) % mod;
		b >>= 1;
	}
	return ans;
}

void frac(int a, int b)
{
	cout << (a * qpow(b, mod - 2)) % mod << endl;
}

signed main()
{
    int n;
    cin >> n;
    int q;
    cin >> q;
    for(int i = 1;i <= n;i++) scanf("%lld", &a[i]);
    build(1, 1, n);
    while(q--)
    {
        int op;
        scanf("%lld", &op);
        if(op == 1)
        {
            int x, y;
            scanf("%lld %lld", &x, &y);
            update(1, x, x, y);
        }
        else if(op == 2)
        {
        	int x, y;
            scanf("%lld %lld", &x, &y);
            int pio = querysum(1, x, y);
            frac((y - x + 1) * querysqr(1, x, y) - (pio * pio), (y - x + 1) * (y - x + 1));
		}
    }
    return 0;
}
2023/10/1 21:57
加载中...