CODECHEF Chef and Churus 解题报告
【CODECHEF】Chef and Churus
Description
有一个长度为\(n\)的数组\(A\),有\(n\)个函数,第\(i\)个函数的值为\(\sum_{j=l_i}^{r_i}A_j\)
有两种操作:
①修改\(A_i\)
②询问第\(l\)~\(r\)个函数值的和。
Input
First Line is the size of the array i.e. N
Next Line contains N space separated numbers Ai denoting the array
Next N line follows denoting Li and Ri for each functions.
Next Line contains an integer Q , number of queries to follow.
Next Q line follows , each line containing a query of Type 1 or Type 2.
1 x y : denotes a type 1 query,where x and y are integers
2 m n : denotes a type 2 query where m and n are integers
Output
For each query of type 2 , output as asked above.
说明
\(1 ≤ N ≤ 10^5,1 ≤ A_i ≤ 10^9,1 ≤ L_i ≤ N,L_i ≤ R_i ≤ N,1 ≤ Q ≤ 10^5\)
\(1 ≤ x ≤ N,1 ≤ y ≤ 10^9,1 ≤ m ≤ N,m ≤ n ≤ N\)
一开始想了个做法,大概是把询问放到线段树的节点上,线段树维护区间和,外面用树状数组维护询问前缀和,然后每次修改的时候暴力改修改一条链的线段树节点上对树状数组的贡献。写完了感觉复杂度有点不对,好像是三个\(\log\)的,又好像可以卡,反正T掉了。
然后正解分块的思路真是神仙%%
对\(A\)进行分块,块内维护快内前缀和,块外维护块的前缀和。这样我们单点修改可以\(O(\sqrt n)\)做,但是询问区间和居然是\(O(1)\)的。
然后对询问进行分块,每个块\(i\)维护一个\(dev_{i,j}\)代表块\(i\)中所有函数覆盖了几个\(j\)这个位置,可以差分进行预处理,再维护一个\(sum_i\)表示这一整块的答案。然后我们发现修改的时候遍历一遍所有块就行了,复杂度是\(O(\sqrt n)\)的
询问的时候,整块直接用\(sum\),散块直接暴力查询区间就可以,复杂度\(O(\sqrt n)\)
于是总复杂度是\(O(n\sqrt n)\)
注意开ull
Code:
#include <cstdio>
#include <cmath>
#define ll unsigned long long
const int N=100010;
const int M=320;
ll F[M],f[N],a[N],sum[M];
int L[N],R[N],dev[M][N],Belong[N],ql[N],qr[N],T,num,n,m;
ll ask(int l,int r)//询问区间的和
{
int lp=Belong[l],rp=Belong[r];
if(lp==rp) return f[r]-(l==L[lp]?0:f[l-1]);
return f[R[lp]]-(l==L[lp]?0:f[l-1])+F[rp-1]-F[lp]+f[r];
}
void modify(int x,ll d)
{
int pos=Belong[x];//改数组块
for(int i=x;i<=R[pos];i++)
f[i]+=d-a[x];
for(int i=pos;i<=num;i++)
F[i]+=d-a[x];
for(int i=1;i<=num;i++)//改询问块
sum[i]+=(d-a[x])*dev[i][x];
a[x]=d;
}
ll query(int l,int r)
{
int lp=Belong[l],rp=Belong[r];
ll ret=0;
if(lp==rp)
{
for(int i=l;i<=r;i++)
ret+=ask(ql[i],qr[i]);
}
else
{
for(int i=l;i<=R[lp];i++)
ret+=ask(ql[i],qr[i]);
for(int i=L[rp];i<=r;i++)
ret+=ask(ql[i],qr[i]);
for(int i=lp+1;i<rp;i++)
ret+=sum[i];
}
return ret;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%llu",f+i),a[i]=f[i];
T=sqrt(n)+1;
for(num=1;num*T<=n;num++) L[num]=T*(num-1)+1,R[num]=T*num;--num;
if(R[num]<n) L[num+1]=R[num]+1,R[++num]=n;
for(int i=1;i<=num;i++)
{
Belong[L[i]]=i;
for(int j=L[i]+1;j<=R[i];j++)
f[j]+=f[j-1],Belong[j]=i;
F[i]+=f[R[i]]+F[i-1];
}
for(int i=1;i<=n;i++) scanf("%d%d",ql+i,qr+i);
for(int i=1;i<=num;i++)
{
for(int j=L[i];j<=R[i];j++)
++dev[i][ql[j]],--dev[i][qr[j]+1];
for(int j=1;j<=n;j++)
dev[i][j]+=dev[i][j-1],sum[i]+=1ll*dev[i][j]*a[j];
}
scanf("%d",&m);
for(int op,l,r,i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&l,&r);
if(op==1) modify(l,r);
else printf("%llu\n",query(l,r));
}
return 0;
}
2018.12.13
CODECHEF Chef and Churus 解题报告的更多相关文章
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
- LeetCode 解题报告索引
最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
随机推荐
- 建表/修改表名/增加删除字段(MySql)
修改表名:alter table 旧表名 rename 新表名; 删除字段:alter table 表名 drop 字段名; 增加字段:alter table 表名 add 字段名 字段类型 [def ...
- equals和==方法比较(二)--Long中equals源码分析
接上篇,分析equals方法在Long包装类中的重写,其他类及我们自定义的类,同样可以根据需要重新equals方法. equals方法定义 equals方法是Object类中的方法,java中所有的对 ...
- JVM知识(上)
目录 什么是JVM? JVM的生命周期 JVM的体系结构 JVM的数据类型 java虚拟机被称为"虚拟",因为它是一个抽象的计算机定义的规范.要运行一个Java程序,需要一个抽象的 ...
- JMeter学习工具简单介绍
JMeter学习工具简单介绍 一.JMeter 介绍 Apache JMeter是100%纯JAVA桌面应用程序,被设计为用于测试客户端/服务端结构的软件(例如web应用程序).它可以用来测试静态 ...
- Siki_Unity_2-7_Stealth秘密行动
Unity 2-7 Stealth秘密行动 Abstract:向量运算:Animation动画:Navigation寻路系统:Mecanim动画系统 任务1&2&3:游戏介绍 & ...
- OpenLDAP搭建部署
安装环境: linu系统: centos7.2版本 OenLDAP:/openldap-2.4.44 下载地址:ftp://ftp.openldap.org/pub/OpenLDAP/ope ...
- Deeplearning - Overview of Convolution Neural Network
Finally pass all the Deeplearning.ai courses in March! I highly recommend it! If you already know th ...
- 性能度量RMSE
回归问题的典型性能度量是均方根误差(RMSE:Root Mean Square Error).如下公式. m为是你计算RMSE的数据集中instance的数量. x(i)是第i个实例的特征值向量 ,y ...
- KETTLE:mongdb与mysql互传数据
注:部分内容引用了 http://blog.sina.com.cn/s/blog_4ac9f56e0101g881.html 1.mongodb传数据到mysql 1)在kettle中,mongodb ...
- Farm Irrigation ZOJ 2412(DFS连通图)
Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot ...