zoukankan      html  css  js  c++  java
  • [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
    ",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;
    }
  • 相关阅读:
    匈牙利游戏
    钓鱼
    路由选择
    借教室
    有趣的数
    广告印刷
    海战
    暑假周进度报告(一)
    在Oracle创建一个自己用的用户及角色
    下载,安装oracle数据库以及navicat连接数据库
  • 原文地址:https://www.cnblogs.com/acmsong/p/7209022.html
Copyright © 2011-2022 走看看