悬赏 5 元求调分块简单题
  • 板块灌水区
  • 楼主typerxiaozhu
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/7/24 08:14
  • 上次更新2024/7/24 09:40:30
查看原帖
悬赏 5 元求调分块简单题
807832
typerxiaozhu楼主2024/7/24 08:14

题目:Codechef Chef and Churu

俺的题解:https://www.luogu.com.cn/paste/vgggg7m0

俺的代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 100005, M = 350;
typedef long long LL;
typedef pair<int, int> PII;
int st[M], ed[M], pos[N];
int t;
LL sum[M];
LL tr[N];
PII func[N];
LL cnt[M][N];
int a[N];
int n, q;
int lowbit(int x)
{
    return x & -x;
}
void add(int x, int c)  
{
    for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}
LL query(int x)  
{
    LL res = 0;
    for (int i = x; i; i -= lowbit(i)) res += tr[i];
    return res;
}
//计算一个函数的值
LL calc(int i)
{
    int L = func[i].first, R = func[i].second;
    LL val = query(R) - query(L - 1);
    return val;
}
void init()
{
    int block = sqrt(n);
    t = n / block;
    if (n % block) t++;
    for (int i = 1; i <= t; i++)
    {
        st[i] = (i - 1) * block + 1;
        ed[i] = i * block;
    }
    ed[t] = n;
    for (int i = 1; i <= n; i++)
    {
        pos[i] = (i - 1) / block + 1;
        sum[pos[i]] += calc(i);
    }
    for (int i = 1; i <= n; i++) 
    {
        int id = pos[i];
        int L = func[i].first, R = func[i].second;
        cnt[id][L]++, cnt[id][R + 1]--;
    }
    for (int i = 1; i <= t; i++)
        for (int j = 1; j <= n; j++)
            cnt[i][j] += cnt[i][j - 1];
}
LL ask(int L, int R)
{
    int p = pos[L], q = pos[R];
    LL res = 0;
    if (p == q)
    {
        for (int i = L; i <= R; i++) res += calc(i);
    }
    else
    {
        for (int i = p + 1; i <= q - 1; i++) res += sum[i];
        for (int i = L; i <= ed[p]; i++) res += calc(i);
        for (int i = st[q]; i <= R; i++) res += calc(i);
    }
    return res;
}
void change(int x, int c)
{
    int d = c - a[x];
    for (int i = 1; i <= t; i++) sum[i] += 1ll * cnt[i][x] * d;
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) 
    {
        scanf("%d", &a[i]);
        add(i, a[i]);
    }
    for (int i = 1; i <= n; i++) 
    {
        int l, r;
        scanf("%d%d", &l, &r);
        func[i] = { l, r };
    }
    scanf("%d", &q);
    init();
    for (int i = 1; i <= q; i++)
    {
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);
        if (op == 1)
        {
            change(x, y);
            add(x, y - a[x]);
            a[x] = y;
        }
        else printf("%lld\n", ask(x, y));
    }
    return 0;
}

Codechef 上面 subtask3 错了一个点,百思不得其解

2024/7/24 08:14
加载中...