FHQ求助
  • 板块P5142 区间方差
  • 楼主luuia
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/8/14 21:29
  • 上次更新2024/8/14 21:56:48
查看原帖
FHQ求助
557800
luuia楼主2024/8/14 21:29

rt.TLE on #10。不知道是代码常数太大还是哪写挂了。

#include<bits/stdc++.h>
using namespace std;

long long read()
{
    long long s = 0,w = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') w = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }
    return s * w;
}

const int N = 1e6 + 10,mod = 1e9 + 7;
long long n,q,x,y,z,l,r,opt,a[N];

long long quickpow(long long c,long long n,long long m)
{
	long long res = 1;
	while(n)
	{
		if(n & 1) res = res * c % m;
		c = c * c % m;
		n >>= 1;
	}	
	return res;
}

struct FHQ
{

long long tot,root;
long long son[N][2],size[N],dat[N],sum[N],val[N],bin[N],cov[N];

void pushup(long long p)
{
    size[p] = size[son[p][0]] + size[son[p][1]] + 1;
    sum[p] = (sum[son[p][0]] + sum[son[p][1]] + val[p]) % mod;
    bin[p] = (bin[son[p][0]] + bin[son[p][1]] + val[p] * val[p] % mod) % mod;
}

void cover(long long p,long long k)
{
    k %= mod;
    cov[p] = k;
    bin[p] = size[p] * k % mod * k % mod;
    sum[p] = k * size[p] % mod;
    val[p] = k;
}

void pushdown(long long p)
{
    if(cov[p] == -1) return;
    if(son[p][0]) cover(son[p][0],cov[p]);
    if(son[p][1]) cover(son[p][1],cov[p]);
    cov[p] = -1;
}

void split(long long p,long long k,long long &x,long long &y)
{
    if(p == 0) {x = y = 0;return;}pushdown(p);
    if(size[son[p][0]] < k) x = p,split(son[p][1],k - size[son[p][0]] - 1,son[p][1],y);
    else y = p,split(son[p][0],k,x,son[p][0]);
    pushup(p);
}

long long merge(long long u,long long v)
{
    if(u == 0 || v == 0) return u + v;
    if(dat[u] < dat[v])
    {
        pushdown(u);
        son[u][1] = merge(son[u][1],v);
        pushup(u);
        return u;
    }
    else
    {
        pushdown(v);
        son[v][0] = merge(u,son[v][0]);
        pushup(v);
        return v;
    }
}

long long New(long long v)
{
    size[++tot] = 1,dat[tot] = rand();
    sum[tot] = bin[tot] = val[tot] = v;
    cov[tot] = -1;
    return tot;
}

long long build(long long l,long long r)
{
    if(l > r) return 0;
    long long mid = l + r >> 1;
    long long k = New(a[mid]);
    son[k][0] = build(l,mid - 1);
    son[k][1] = build(mid + 1,r);
    pushup(k);
    return k;
}

long long Query_sum(long long l,long long r)
{
    split(root,r,x,z);
    split(x,l - 1,x,y);
    long long tmp = sum[y];
    root = merge(merge(x,y),z);
    return tmp;
}

long long Query_bin(long long l,long long r)
{
    split(root,r,x,z);
    split(x,l - 1,x,y);
    long long tmp = bin[y];
    root = merge(merge(x,y),z);
    return tmp;
}

void Cov(long long l,long long r,long long k)
{
    split(root,r,x,z);
    split(x,l - 1,x,y);
    cover(y,k);
    root = merge(merge(x,y),z);
}

void print(long long p)
{
    if(son[p][0]) print(son[p][0]);
    cout << val[p] << " ";
    if(son[p][1]) print(son[p][1]);
}

}tree;

int main()
{
    // freopen("input.in","r",stdin);
    n = read(),q = read();
    for(int i = 1;i <= n;i++) a[i] = read();
    tree.root = tree.build(1,n);
    while(q--)
    {
        opt = read(),l = read(),r = read();
        if(opt == 1) tree.Cov(l,l,r);
        if(opt == 2) 
        {
            long long tmp = tree.Query_sum(l,r);
            if(r - l + 1 < 0) return 0;
            cout << (((r - l + 1) * tree.Query_bin(l,r) % mod - tmp * tmp % mod) % mod + mod) % mod * quickpow((r - l + 1) * (r - l + 1) % mod,mod - 2,mod) % mod << endl;
        }
        // tree.print(tree.root),cout << endl;
    }
    return 0;
}
2024/8/14 21:29
加载中...