[codechef FNCS]分块处理+树状数组

Posted ACMsong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[codechef FNCS]分块处理+树状数组相关的知识,希望对你有一定的参考价值。

题目链接:https://vjudge.net/problem/CodeChef-FNCS

在一个地方卡了一晚上,就是我本来以为用根号n分组,就会分成根号n个。事实上并不是。。。。因为用的是根号n下取整分组,得到的组数要用n/floor(sqrt(n))具体计算。

另外还有各种奇怪的bug……包括unsigned long long什么的……orz

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int maxn=100005;
int a[maxn];
int fl[maxn],fr[maxn];
int cnt[maxn][320];
ull res[320];
ull tree[maxn];
int N,block_size;

int lowbit(int x)
{
    return x&-x;
}

void add(int k,int x)
{
    while (k<=N)
    {
        tree[k]+=x;
        k+=lowbit(k);
    }
}

ull query(int k)
{
    ull res=0ull;
    while (k)
    {
        res+=tree[k];
        k-=lowbit(k);
    }
    return res;
}

void init(int n)
{
    N=n;
    for (int i=1;i<=N;i++) tree[i]=0ull;
}

ull query2(int k)
{
    if (k<1) return 0;
    ull r=0ull;
    int block_id=(k-1)/block_size+1;
    for (int i=1;i<block_id;i++) r+=res[i];
    for (int i=(block_id-1)*block_size+1;i<=k;i++)
    {
        r+=query(fr[i])-query(fl[i]-1);
    }
    return r;
}

int main()
{
    int n;
    scanf("%d",&n); 
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=1;i<=n;i++) scanf("%d%d",&fl[i],&fr[i]);
    block_size=sqrt(n);
    int block=n/block_size;
    for (int i=1;i<=block;i++)
    {
        for (int j=(i-1)*block_size+1;j<=i*block_size;j++)
        {
            cnt[fr[j]+1][i]--;
            cnt[fl[j]][i]++;
        }
        res[i]=0;
        for (int j=1;j<=n;j++)
        {
            cnt[j][i]+=cnt[j-1][i];
            res[i]+=1ull*a[j]*cnt[j][i];
        }
    }
    init(n);
    for (int i=1;i<=n;i++) add(i,a[i]);
    int q;
    scanf("%d",&q);
    while (q--)
    {
        int op,x,y;
        scanf("%d%d%d",&op,&x,&y);
        if (op==2)
        {
            ull r=query2(y)-query2(x-1);
            printf("%llu\n",r);
        }
        else
        {
            for (int i=1;i<=block;i++)
            {
                res[i]+=1ull*cnt[x][i]*(y-a[x]);
            }
            add(x,y-a[x]);
            a[x]=y;
        }
    }
    return 0;
}

 

以上是关于[codechef FNCS]分块处理+树状数组的主要内容,如果未能解决你的问题,请参考以下文章

[数据结构学习]分块与树状数组

CodeChef - QCHEF 分块

BZOJ4167永远的竹笋采摘 分块+树状数组

Codeforces 785 E. Anton and Permutation(分块,树状数组)

Bzoj 2141: 排队 分块,逆序对,树状数组

bzoj3295动态逆序对 分块+树状数组