CodeChef FNCS
题面:https://www.codechef.com/problems/FNCS
题解:
我们考虑对 n 个函数进行分块,设块的大小为S。
每个块内我们维护当前其所有函数值的和,以及数组中每个元素对这个块函数值的和的贡献系数。
那么每次修改操作我们就可以对每个块函数值的和 O(1)进行修改。
对于询问,落在完整块内的部分我们维护了它的和,直接 O(1)调用即可。
剩余的部分我们对每个函数依次求值。
那么现在问题就变为单点修改、询问区间和。
如果我们使用树状数组,那么单次询问与单次修改复杂度操作均为 O(logn),
而询问操作数目远多于修改操作导致时间效率不平衡。
所以我们对原数组求一遍前缀和,然后问题变为区间修改、单点查询,
这个我们用分块便可以做到 O(S+n/S)修改和 O(1)询问了。
PS:此题卡long long,要用unsigned long long。。。
code:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
typedef unsigned long long int64;
const int maxs=;
const int maxn=;
int n,q,siz,lim,op,l,r,x,y,bel[maxn];
struct Data{
int l,r;
}block[maxs],seg[maxn];
int a[maxn];
int f[maxs][maxn];
int64 res[maxs],sum[maxs][maxs],tag[maxs];
struct Seg{
int add[maxn<<];
void init(){memset(add,,sizeof(add));}
void pushdown(int k){if (add[k]) add[k<<]+=add[k],add[(k<<)+]+=add[k],add[k]=;}
void modify(int k,int l,int r,int x,int y){
if (l==x&&r==y){add[k]++;return;}
int m=(l+r)>>;
if (y<=m) modify(k<<,l,m,x,y);
else if (x<=m) modify(k<<,l,m,x,m),modify((k<<)+,m+,r,m+,y);
else modify((k<<)+,m+,r,x,y);
}
void get(int k,int l,int r,int id){
if (l==r){f[id][l]=add[k],res[id]+=1ULL*add[k]*a[l];return;}
int m=(l+r)>>;
pushdown(k);
get(k<<,l,m,id),get((k<<)+,m+,r,id);
}
}T;
void add(int x,int v){
int id=bel[x],st=id;
if (x>block[id].l){
for (int i=x;i<=block[id].r;i++) sum[id][i-block[id].l]+=v;
st++;
}
for (int i=st;i<=lim;i++) tag[i]+=v;
}
int64 query(int x){
if (!x) return ;
int id=bel[x];
return sum[id][x-block[id].l]+tag[id];
}
void modify(int x,int v){
add(x,-a[x]);
for (int i=;i<=lim;i++) res[i]-=1ULL*f[i][x]*a[x];
a[x]=v;
add(x,a[x]);
for (int i=;i<=lim;i++) res[i]+=1ULL*f[i][x]*a[x];
}
void query(int l,int r){
int64 ans=;
int st=bel[l],ed=bel[r];
if (st!=ed){
if (l>block[st].l){
for (int i=l;i<=block[st].r;i++) ans+=query(seg[i].r)-query(seg[i].l-);
st++;
}
if (r<block[ed].r){
for (int i=block[ed].l;i<=r;i++) ans+=query(seg[i].r)-query(seg[i].l-);
ed--;
}
for (int i=st;i<=ed;i++) ans+=res[i];
}
else for (int i=l;i<=r;i++) ans+=query(seg[i].r)-query(seg[i].l-);
printf("%llu\n",ans);
}
int main(){
read(n),siz=sqrt(n);
for (int i=;i<=n;i++){
bel[i]=i/siz+;
if (!block[bel[i]].l) block[bel[i]].l=i;
block[bel[i]].r=i;
}
lim=bel[n];
for (int i=;i<=n;i++) read(a[i]),add(i,a[i]);
for (int i=;i<=n;i++){
if (block[bel[i]].l==i) T.init();
read(l),read(r),seg[i]=(Data){l,r};
T.modify(,,n,l,r);
if (block[bel[i]].r==i) T.get(,,n,bel[i]);
}
for (read(q);q;q--){
read(op),read(x),read(y);
if (op==) modify(x,y);
else query(x,y);
}
return ;
}
CodeChef FNCS的更多相关文章
- CodeChef FNCS (分块+树状数组)
题目:https://www.codechef.com/problems/FNCS 题解: 我们知道要求区间和的时候,我们用前缀和去优化.这里也是一样,我们要求第 l 个函数到第 r 个函数 [l, ...
- Chef and Problems(from Code-Chef FNCS) ( 回 滚 )
题目: 题意:给定序列,求[l,r]区间内数字相同的数的最远距离. 链接:https://www.codechef.com/problems/QCHEF #include<bits/stdc++ ...
- CodeChef - FNCS Chef and Churu(分块)
https://vjudge.net/problem/CodeChef-FNCS 题意: 思路: 用分块的方法,对每个函数进行分块,计算出该分块里每个数的个数,这样的话也就能很方便的计算出这个分块里所 ...
- [codechef FNCS]分块处理+树状数组
题目链接:https://vjudge.net/problem/CodeChef-FNCS 在一个地方卡了一晚上,就是我本来以为用根号n分组,就会分成根号n个.事实上并不是....因为用的是根号n下取 ...
- Codechef FNCS Chef and Churu
Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...
- ZJOI2019一轮停课刷题记录
Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...
- 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ...
- 【BZOJ4260】 Codechef REBXOR 可持久化Trie
看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...
随机推荐
- MySQL可视化管理工具 —— Navicat for MysSQL
类似PL/SQL管理Oracle的工具 Navicat可以管理MySQL 1.安装 2.连接(输入IP.端口.用户名.密码) 3.新建sql语句:点击左侧database.点击菜单“查询”.点击“新建 ...
- html或jsp实现打印三种方法
1.使用window.print()方法 优点:支持多浏览器 缺点:取消打印,隐藏打印不必要的信息后再显示比较麻烦 如下实现,可以打印当前页面 <input name ="Button ...
- OpenCV 2.4.9
2014.4.25 感谢那些參加开发.发送错误报告以及通过其它方式帮助我们的全部人和公司. 源代码如今已经可以从SourceForge和Github上下载了. 2.4.9版本号的帮助文章也更新到如今的 ...
- CMake高速入门
入门基础:http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ 在 linux 下使用 CMake 构建应用程序 入门进阶:http ...
- cubieboard变身AP 分类: ubuntu cubieboard 2014-11-25 14:04 277人阅读 评论(0) 收藏
加载bcmdhd模块:# modprobe bcmdhd 如果你希望开启 AP 模式,那么:# modprobe bcmdhd op_mode=2 在/etc/modules文件内添加bcmdhd o ...
- gitlab hooks
之前一直用文件同步工具进行两台服务器之间的同步 最初的目的是吧gitlab的代码库同步到开发环境中运行 实时的 ,后来由于gitlab的代码仓库的代码不是实时的 于是在即使同步不适合 我的需求. 后来 ...
- 判断IMEI或MEID是否合法
/*----------------------------------------------- * 判断此字串所代表的IMEI或MEID是否合法 * @param imei * @author H ...
- Cocos2d各版本搭建环境中的奇葩操作
#Version: Cocos2d-x 3.4 Android 将[Cocos2d-x解压目录]\cocos\platform\android\java\src中的com,org目录拷贝覆盖到[项目根 ...
- Android 布局
转自:http://www.cnblogs.com/chiao/archive/2011/08/24/2152435.html Android布局是应用界面开发的重要一环,在Android中,共有五种 ...
- windows使用python调用wget批处理下载数据
wget是linux/unix下通常使用的下载http/ftp的数据,使用非常方便,其实wget目前经过编译,也可在windows下使用.最近需要下载大量的遥感数据,使用了python写了批处理下载程 ...