题目大意

有一个长度为n的数组A

有n个函数,第i个函数 $$f(l[i],r[i])=\sum_{k=l[i]}^{r[i]}A_k$$

有两种操作:

1)修改A[i]

2)询问第x-y个函数值的和。

数据范围:n<=100000

分析1

考虑询问时x=y的情况

如何用尽可能快的速度回答询问?

维护\(sum1[i]\)表示前i块的前缀和

维护\(sum2[i][j]\)表示第i块中的前j个数的前缀和

修改时暴力维护\(sum2\),接着暴力维护\(sum1\)

复杂度\(O(2*\sqrt n)\)

询问就可以\(O(1)\)了

分析2

如何结局区间函数询问呢

我们对函数也分块

维护\(all[i]\)表示第i块函数的值

维护\(cov[i][j]\)表示第\(i\)块中,有多少个函数包含\(A[j]\)

对于\(cov\)数组,它是不会改变的

预处理时对于每块扫一次

用差分+前缀和的方法做到\(O(n\sqrt n)\)

对于\(all\)

每次修改时扫一下\(\sqrt n\)个块,用\(cov\)数组看下修改的那个单点对这个块的\(all\)的影响

注意

别再把BL,BR写成x,y了好嘛?

solution

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
const int M=100007;
const int N=320;
typedef unsigned long long LL; inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
} int n,m,sn,MX;
LL val[M];
struct node{int l,r;}q[M]; LL sum1[N];
LL sum2[N][N];
LL cov[N][M];
LL all[N]; int loc(int x){
return x/sn+1;
} int getL(int x){
return max((x-1)*sn,1);
} int getR(int x){
return min(x*sn-1,n);
} int getP(int x){
int L=getL(loc(x));
return x-L+1;
} void init_sum(int x){
int i,L=getL(x),R=getR(x);
LL nw=0;
for(i=L;i<=R;i++){
nw+=val[i];
sum2[x][getP(i)]=nw;
}
sum2[x][sn]=nw;//这样方便
for(int i=x;i<=MX;i++) sum1[i]=sum1[i-1]+sum2[i][sn];
} LL get_sum(int x,int y){
int L,R,BL,BR;
BL=loc(x); BR=loc(y);
if(BL+1>=BR){
if(BL==BR) return sum2[BL][getP(y)]-sum2[BL][getP(x)-1]; return sum2[BR][getP(y)]-sum2[BL][getP(x)-1]+sum2[BL][sn];
}
else{
if(getL(BL)!=x) BL++;
if(getR(BR)!=y) BR--;
L=getL(BL); R=getR(BR);
LL res=sum1[BR]-sum1[BL-1];
if(R!=y) res+=sum2[BR+1][getP(y)];
if(L!=x) res+=sum2[BL-1][sn]-sum2[BL-1][getP(x)-1];
return res;
}
} void init_cov(int x){
int L=getL(x),R=getR(x);
for(int i=L;i<=R;i++){
cov[x][q[i].l]++;
cov[x][q[i].r+1]--;
all[x]+=get_sum(q[i].l,q[i].r);
}
for(int i=1;i<=n;i++){
cov[x][i]+=cov[x][i-1];
}
} int main(){
int i,kd,x,y,BL,BR,L,R;
n=rd();
sn=(int)sqrt(n);
MX=loc(n); for(i=1;i<=n;i++) val[i]=rd(); for(i=1;i<=n;i++) q[i].l=rd(),q[i].r=rd(); for(i=1;i<=MX;i++) init_sum(i);
for(i=1;i<=MX;i++)
init_cov(i); m=rd(); while(m--){
kd=rd();
x=rd(),y=rd();
if(kd==1){
y-=val[x];
val[x]+=y;
init_sum(loc(x));
for(i=1;i<=MX;i++) all[i]+=cov[i][x]*y;
}
else{
LL ans=0;
BL=loc(x); BR=loc(y); if(BL+1>=BR){
for(i=x;i<=y;i++) ans+=get_sum(q[i].l,q[i].r);
}
else{
if(getL(BL)!=x) BL++;
if(getR(BR)!=y) BR--;
L=getL(BL); R=getR(BR);
for(i=BL;i<=BR;i++) ans+=all[i];
for(i=x;i<L;i++) ans+=get_sum(q[i].l,q[i].r);
for(i=y;i>R;i--) ans+=get_sum(q[i].l,q[i].r);
}
printf("%llu\n",ans);
}
} return 0;
}

chef and churu 分块 好题的更多相关文章

  1. CodeChef Chef and Churu [分块]

    题意: 单点修改$a$ 询问$a$的区间和$f$的区间和 原来普通计算机是这道题改编的吧... 对$f$分块,预处理$c[i][j]$为块i中$a_j$出现几次,$O(NH(N))$,只要每个块差分加 ...

  2. 【Codechef-Hard】Chef and Churu 分块

    题目链接: https://www.codechef.com/problems/FNCS Solution 大力分块.. 对序列分块,维护块内前缀和.块的前缀和,修改时暴力维护两个前缀和,询问单点答案 ...

  3. [CC-FNCS]Chef and Churu

    [CC-FNCS]Chef and Churu 题目大意: 一个长度为\(n(n\le10^5)\)的数列\(A_{1\sim n}\),另有\(n\)个函数,第\(i\)个函数会返回数组中标号在\( ...

  4. Codechef FNCS Chef and Churu

    Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...

  5. BZOJ 2724 蒲公英 | 分块模板题

    题意 给出一个序列,在线询问区间众数.如果众数有多个,输出最小的那个. 题解 这是一道分块模板题. 一个询问的区间的众数,可能是中间"整块"区间的众数,也可能是左右两侧零散的数中的 ...

  6. Luogu 2801 教主的魔法 | 分块模板题

    Luogu 2801 教主的魔法 | 分块模板题 我犯的错误: 有一处l打成了1,还看不出来-- 缩小块大小De完bug后忘了把块大小改回去就提交--还以为自己一定能A了-- #include < ...

  7. hzwer分块九题(暂时持续更新)

    hzwer分块9题 分块1:区间加法,单点查询 Code #include<bits/stdc++.h> #define in(i) (i=read()) using namespace ...

  8. CodeChef - FNCS Chef and Churu(分块)

    https://vjudge.net/problem/CodeChef-FNCS 题意: 思路: 用分块的方法,对每个函数进行分块,计算出该分块里每个数的个数,这样的话也就能很方便的计算出这个分块里所 ...

  9. 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu

    https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...

随机推荐

  1. 《队长说得队》第九次团队作业:Beta冲刺与验收准备

    项目 内容 这个作业属于哪个课程 >>2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 >>实验十三 团队作业9:Beta冲刺与团队项目验收 团队名 ...

  2. 剑指offer题目分类

    1. 链表 1. 从尾到头打印链表 2. 链表中倒数第k个结点 3. 反转链表 4. 合并两个排序的链表 5. 复杂链表的复制 6. 复杂链表的复制 7. 两个链表的第一个公共结点 8. 链表中环的入 ...

  3. CPL学习笔记(二)

    数组 数组(array) 声明通用格式为: typeName arrayName[arraySize]. arrayName指定元素数目,必须为整型常量或const值.(不能是变量) int a[3] ...

  4. PHPStorm+XDebug进行调试图文教程

    这篇文章主要为大家详细介绍了PHPStorm+XDebug进行调试图文教程,内容很丰富,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 另外如果你们加载不出图片,另外的地址:转载地址https:// ...

  5. MySQL左右连接查询中的NULL的数据筛选问题

    这里使用左连接为例子,对于左连接是将左边表的数据显示,右边表中如果没有对应的数据则使用null填充. game表: game_type表: SELECT g.name,g.type_id,t.type ...

  6. 201621123080《Java程序设计》第12周学习总结

    201621123080<Java程序设计>第12周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系 ...

  7. linux文件属性之用户和组基础知识

    root               :x                  :0                  :0                  :root                 ...

  8. VNC远程登录端使用经验之一

    1.vnc/xmanager都是经常用的远程登录软件.vnc有个缺点就是他的进程不会自动退出比如如果开了PID1再去开PID2...PIDn.那么前面的PIDn-1个进程就会一直运行如果不手动kill ...

  9. 【 android】When an app is installed on the external storage

    When an app is installed on the external storage: The .apk file is saved to the external storage, bu ...

  10. java代码导出数据到Excel、js导出数据到Excel(三)

     jsp内容忽略,仅写个出发按钮:          <button style="width: 100px" onclick="expertExcel()&quo ...