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,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
随机推荐
- Unity初级案例——贪吃蛇
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; ...
- Redis5.0:现公测全免费,点击就送,注册账号,即开即用
华为云分布式缓存服务Redis,是华为云服务的一款核心产品. 分布式缓存Redis是一款内存数据库服务,基于双机热备的高可用架构,提供单机.主从.集群等丰富类型的缓存类型. 现推出最新版本Redis5 ...
- UVa 10071
简单运动学公式 v=v0+at x=v0t+1/2*a*t^2=2vt #include<stdio.h> int main() { int v, t; while((scanf(&quo ...
- JavaScript 之 ajax
1. AJAX 的概念 AJAX,即 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML) 同步:前面的代码不执行完毕,后面的代码无法执行 异步: ...
- Selenium WebDriver 下 plugin container for firefox has stopped working
用selenium 的webdriver 和 firefox 浏览器做自动化测试,经常会出现 plugin container for firefox has stopped working 如下图所 ...
- Python基础知识-05-数据类型总结字典
python其他知识目录 1.一道题,选择商品的序号.程序员和用户各自面对的序号起始值 如有变量 googs = ['汽车','飞机','火箭'] 提示用户可供选择的商品: 0,汽车1,飞机2,火箭用 ...
- GitHub 的简单使用
GitHub 的简单使用 2016-01-28 16:32:481909浏览1评论 一.Git 版本控制器 commit:做一个版本:commit new file:添加到版本中,下边填的是项目的描述 ...
- 解决Ubuntu16.04下git clone太慢问题
记录一些博客,省着自己再去找了... ss-qt5安装 生成.pac genpac --pac-proxy "SOCKS5 127.0.0.1:1080" --gfwlist-pr ...
- SGU 126 Boxes(模拟题|二进制)
Translate:Sgu/126 126. 盒子 time limit per test: 0.5 sec. memory limit per test: 4096 KB 有两个盒子. 第一个盒子里 ...
- hihocoder #1032 : 最长回文子串 Manacher算法
题目链接: https://hihocoder.com/problemset/problem/1032?sid=868170 最长回文子串 时间限制:1000ms内存限制:64MB 问题描述 小Hi和 ...