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} ...
随机推荐
- android 2048游戏、kotlin应用、跑马灯、动画源码
Android精选源码 2048游戏源码 android实现获取号码归属地和其他信息诈骗.骚扰 android kotlin仿开眼app源码 android多种reveal动画效果 android K ...
- CSS中的定位与浮动
CSS中的定位与浮动 本文主要讲述CSS中的三种定位样式static.relative和absolute的区别以及浮动元素的特征. 定位样式 CSS中定位样式position的取值有三个,默认值:st ...
- 平安E行销扫脸打卡/人寿国寿e店云参会钉钉考勤,原来这么轻易被破解!
由于近几年人们的保险意识越来越强,身边有很多朋友都在中国人寿,中国平安等保险公司上班薪水高,工作自由,又可以学习很多保险理财的知识,每天早会个2~3个小时,剩下的基本都是自己的时间,(vx:99508 ...
- git常用命令--转载
http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
- vue 开发2017年变化回顾及2018年展望
vue.js 变化 从 github 的发布记录我们可以看到2017年 vue.js 的第一个发布为 v2.1.9,最后一个为 v2.5.13,主要发布小版本 2.2~2.5.这些发布提升了vue 与 ...
- 通读cheerio API ——NodeJs中的jquery
通读cheerio API ——NodeJs中的jquery 所谓工欲善其事,必先利其器,所以通读了cheerio的API,顺便翻译了一遍,有些地方因为知道的比较少,不知道什么意思,保留了英文,希望各 ...
- Selenium滚动条window.scrollTo和window.scrollBy
Selenium操作滚动条有两种方法,一种就是window.scrollTo,另一种是window.scrollBy,既然两个都可以用来操作滚动条,那这两个方法有什么区别呢? 1.window.scr ...
- hive(II)--sql考查的高频问题
在了解别人hive能力水平的时候,不管是别人问我还是我了解别人,有一些都是必然会问的东西.问的问题也大都大同小异.这里总结一下我遇到的那些hive方面面试可能涉及的问题 1.行转列(列转行) 当我们建 ...
- linux_软件安装策略和升级策略
运维3大原则:可靠.稳定.简单 尝试新的软件,一切都是未知的,也就是说不可靠,不可预测也就意味的不稳定,解决问题,通过百度和谷歌工具有可能找不到解决方法,只能通过官方文档来解决问题,大大增加了排错时间 ...
- 译-what is cmdlet
A cmdlet (pronounced "command-let") is a lightweight Windows PowerShell script that perfor ...