CodeChef Chef and Churu [分块]
题意:
单点修改$a$
询问$a$的区间和$f$的区间和
原来普通计算机是这道题改编的吧...
对$f$分块,预处理$c[i][j]$为块i中$a_j$出现几次,$O(NH(N))$,只要每个块差分加上然后扫一遍就行了不用树状数组之类的
修改,整块直接改,还要单点修改$a$
查询,整块直接查,两边暴力查询$a$的区间和
对$a$的操作可以用树状数组,也可以再分块维护前缀和实现$O(N)-O(1)$
这样不用带一个log总复杂度$O(NH(N))$
实测快了0.4s
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1e5+,M=;
typedef unsigned long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,Q,op,x,y;
ll a[N],s[N];
int pos[N],m,block;
struct _Block{int l,r;} b[M], f[N];
inline void iniBlock(){
block=sqrt(n); m=(n-)/block+;
for(int i=;i<=n;i++) pos[i]=(i-)/block+;
for(int i=;i<=m;i++) b[i].l=(i-)*block+,b[i].r=i*block;
b[m].r=n;
}
struct BlockA{
ll add[M];
void Add(int x,ll v){
for(int i=x;i<=b[pos[x]].r;i++) s[i]+=v;
for(int i=pos[x]+;i<=m;i++) add[i]+=v;
}
ll fun(_Block &x){
return s[x.r]+add[ pos[x.r] ] - (s[x.l-]+add[ pos[x.l-] ]);
}
}A;
struct Block{
int c[M][N],s[N];
ll sum[N];
void ini(){
for(int i=;i<=m;i++){
for(int j=b[i].l ; j<=b[i].r ; j++)
s[ f[j].l ]++,s[ f[j].r+ ]--;
int *cc=c[i];
for(int j=;j<=n;j++)
cc[j]=cc[j-]+s[j],sum[i]+=cc[j]*a[j],s[j]=;
}
}
void cha(int x,ll v){
ll t=v-a[x]; A.Add(x,t);
for(int i=;i<=m;i++) sum[i]+=c[i][x]*t;
a[x]=v;
}
ll que(int l,int r){
ll re=;
if(pos[l]==pos[r])
for(int i=l;i<=r;i++) re+=A.fun(f[i]);
else{
for(int i=pos[l]+;i<=pos[r]-;i++) re+=sum[i];
for(int i=l;i<=b[pos[l]].r;i++) re+=A.fun(f[i]);
for(int i=b[pos[r]].l;i<=r;i++) re+=A.fun(f[i]);
}
return re;
}
}B;
int main(){
freopen("in","r",stdin);
n=read();
for(int i=;i<=n;i++) a[i]=read(),s[i]=s[i-]+a[i];
for(int i=;i<=n;i++) f[i].l=read(),f[i].r=read();
iniBlock();B.ini();
Q=read();
while(Q--){
op=read();x=read();y=read();
if(op==) B.cha(x,y);
else printf("%llu\n",B.que(x,y));
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define pii pair<int,int>
#define MP make_pair
#define fir first
#define sec second
const int N=1e5+,M=;
typedef unsigned long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,Q,op,x,y;
ll a[N];
pii f[N];
struct BIT{
ll c[N];
inline void add(int p,ll v){for(;p<=n;p+=(p&-p)) c[p]+=v;}
inline ll sum(int p){ll re=;for(;p;p-=(p&-p)) re+=c[p];return re;}
}C;
inline ll fun(int x){return C.sum(f[x].sec)-C.sum(f[x].fir-);}
struct _Block{int l,r;ll sum;};
struct Block{
int block,m,pos[N],c[M][N],s[N];
_Block b[M];
void ini(){
block=sqrt(n); m=(n-)/block+;
for(int i=;i<=n;i++) pos[i]=(i-)/block+; for(int i=;i<=m;i++){
b[i].l=(i-)*block+; b[i].r= i==m ? n : i*block;
for(int j=b[i].l ; j<=b[i].r ; j++)
s[ f[j].fir ]++,s[ f[j].sec+ ]--;
int *cc=c[i];
for(int j=;j<=n;j++) cc[j]=cc[j-]+s[j],b[i].sum+=cc[j]*a[j],s[j]=;
}
}
void cha(int x,ll v){
v-=a[x];
for(int i=;i<=m;i++) b[i].sum+=c[i][x]*v;
C.add(x,v); a[x]+=v;
}
ll que(int l,int r){
ll re=;
if(pos[l]==pos[r])
for(int i=l;i<=r;i++) re+=fun(i);
else{
for(int i=pos[l]+;i<=pos[r]-;i++) re+=b[i].sum;
for(int i=l;i<=b[pos[l]].r;i++) re+=fun(i);
for(int i=b[pos[r]].l;i<=r;i++) re+=fun(i);
}
return re;
}
}B;
int main(){
freopen("in","r",stdin);
n=read();
for(int i=;i<=n;i++) a[i]=read(),C.add(i,a[i]);
for(int i=;i<=n;i++) f[i].fir=read(),f[i].sec=read();
B.ini();
Q=read();
while(Q--){
op=read();x=read();y=read();
if(op==) B.cha(x,y);
else printf("%llu\n",B.que(x,y));
}
}
BIT
CodeChef Chef and Churu [分块]的更多相关文章
- 【Codechef-Hard】Chef and Churu 分块
题目链接: https://www.codechef.com/problems/FNCS Solution 大力分块.. 对序列分块,维护块内前缀和.块的前缀和,修改时暴力维护两个前缀和,询问单点答案 ...
- chef and churu 分块 好题
题目大意 有一个长度为n的数组A 有n个函数,第i个函数 \[f(l[i],r[i])=\sum_{k=l[i]}^{r[i]}A_k\] 有两种操作: 1)修改A[i] 2)询问第x-y个函数值的和 ...
- Codechef FNCS Chef and Churu
Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...
- CodeChef:Chef and Problems(分块)
CodeChef:Chef and Problems 题目大意 有一个长度为n的序列$a_1,a_2,……,a_n$,每次给出一个区间[l,r],求在区间内两个相等的数的最远距离($max(j-i,满 ...
- [CC-FNCS]Chef and Churu
[CC-FNCS]Chef and Churu 题目大意: 一个长度为\(n(n\le10^5)\)的数列\(A_{1\sim n}\),另有\(n\)个函数,第\(i\)个函数会返回数组中标号在\( ...
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...
- CodeChef - FNCS Chef and Churu(分块)
https://vjudge.net/problem/CodeChef-FNCS 题意: 思路: 用分块的方法,对每个函数进行分块,计算出该分块里每个数的个数,这样的话也就能很方便的计算出这个分块里所 ...
- 【xsy2111】 【CODECHEF】Chef and Churus 分块+树状数组
题目大意:给你一个长度为$n$的数列$a_i$,定义$f_i=\sum_{j=l_i}^{r_i} num_j$. 有$m$个操作: 操作1:询问一个区间$l,r$请你求出$\sum_{i=l}^{r ...
- CODECHEF Chef and Churus 解题报告
[CODECHEF]Chef and Churus Description 有一个长度为\(n\)的数组\(A\),有\(n\)个函数,第\(i\)个函数的值为\(\sum_{j=l_i}^{r_i} ...
随机推荐
- [学习OpenCV攻略][008][Canny边缘检测]
cvGetSize(输入图片) 得到输入图片的大小 cvCanny(输入图片,输出图片,lowThresh,highThresh,aperture) 把输入图片按设定光圈值进行Canny边缘检测,然后 ...
- Spider_Man_5.2 の Mongodb_使用
一:简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库1.易用性 MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库.不采用关系型主要是为了获得 ...
- Spring MVC集成Swagger
什么是Swagger? 大部分 Web 应用程序都支持 RESTful API,但不同于 SOAP API——REST API 依赖于 HTTP 方法,缺少与 Web 服务描述语言(Web Servi ...
- 规范的python编码
规范的 python 编码令人赏心悦目,令代码的表达逻辑更清晰,使得工程代码更容易被维护和交流: 编码规范包括对于代码书写格式的约束,不良语法的禁用和推荐的编码手法,下面做些简要的描述: 1. 代码规 ...
- ThinkPHP模板IF标签用法详解
投稿:shichen2014 字体:[增加 减小] 类型:转载 时间:2014-07-01 我要评论 这篇文章主要介绍了ThinkPHP模板IF标签用法,需要的朋友可以参考下 ThinkPHP的IF标 ...
- php数组根据某一个键值,把相同键值的合并生成一个新的二维数组
http://blog.csdn.net/xyzchenxiaolin/article/details/51700485 源数据: $infos = array( array( 'a' => 3 ...
- 邓_ phpcms_
{pc:content action="lists" catid="$catid" num="10" order="id DESC ...
- dedecms_插件
../dede/adbaoming.php../dede/baoming_edit.php../dede/templets/baoming_main.htm
- RequireJS(一)
RequireJS: RequireJS中文网:http://www.requirejs.cn/ 解决HTML引入大量js文件导致的问题: 首先是加载的时候,浏览器会停止网页渲染,加载文件越多,网页失 ...
- Hyperledger Fabric Membership Service Providers (MSP)——成员服务
Membership Service Providers (MSP) 本文将介绍有关MSPs的设置和最佳实践的详细方案. Membership Service Providers (MSP)是一个旨在 ...