题面: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的更多相关文章

  1. CodeChef FNCS (分块+树状数组)

    题目:https://www.codechef.com/problems/FNCS 题解: 我们知道要求区间和的时候,我们用前缀和去优化.这里也是一样,我们要求第 l 个函数到第 r 个函数 [l, ...

  2. Chef and Problems(from Code-Chef FNCS) ( 回 滚 )

    题目: 题意:给定序列,求[l,r]区间内数字相同的数的最远距离. 链接:https://www.codechef.com/problems/QCHEF #include<bits/stdc++ ...

  3. CodeChef - FNCS Chef and Churu(分块)

    https://vjudge.net/problem/CodeChef-FNCS 题意: 思路: 用分块的方法,对每个函数进行分块,计算出该分块里每个数的个数,这样的话也就能很方便的计算出这个分块里所 ...

  4. [codechef FNCS]分块处理+树状数组

    题目链接:https://vjudge.net/problem/CodeChef-FNCS 在一个地方卡了一晚上,就是我本来以为用根号n分组,就会分成根号n个.事实上并不是....因为用的是根号n下取 ...

  5. Codechef FNCS Chef and Churu

    Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...

  6. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

  7. 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu

    https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...

  8. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  9. 【BZOJ4260】 Codechef REBXOR 可持久化Trie

    看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...

随机推荐

  1. MySQL 面试基础

    相关:http://blog.csdn.net/u013252072/article/details/52912385          http://blog.csdn.net/zhangliang ...

  2. 洛谷 P1004 方格取数

    题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...

  3. python 多级菜单 纯循环与分支

    源代码: dic1 = {'湖南':{'衡阳':{'珠晖区':'湖南工学院'},'湘潭':{'晖晖':'啦啦'}}, '北京':{'朝阳': {"德玛:北京大学"}}}print( ...

  4. Nunit Test 项目模块

    下载地址:http://visualstudiogallery.msdn.microsoft.com/97bd5118-0c29-41b4-9477-d34192c183c3?SRC=VSIDE

  5. 触发器记录表某一个字段数据变化的日志 包括插入insert 修改update 删除delete 操作

    本文参考:http://www.cnblogs.com/lyhabc/articles/3236985.html ,),  ),               ),           ),       ...

  6. Android Layout布局文件里的android:layout_height等属性不起作用

    有的时候,我们配置好的布局文件,在加载完成添加到我们的Activity中后发现,并没有安装我们设置的属性 来布局,比为我们设置了android:layout_marginTop="100di ...

  7. Nubia Z5S(高通公司MSM8974) QHSUSB_BULK砖的方法节省模式(随着win7在恢复recovery分区案例)

    Nubia Z5S在某些异常情况或按组合键进入QHSUSB_BULK状态, 这种模式的现象, 猜想windows(实例win7)即使在数据线, 它会出现在计算机n载,甚至会提示要格式化某些分区(这里要 ...

  8. Bit data type

    mysql> create table t(a bit()); Query OK, rows affected (0.04 sec) mysql> insert into t '; Que ...

  9. linux 内核分析+使用SystemTap调试新增内核模块

    http://blog.chinaunix.net/uid/14528823/list/1.html?cid=189394

  10. windows 下解决 Time_Wait 和 CLOSE_WAIT 方法

    修改Time_Wait参数的方法 (在服务端修改)Windows下在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Paramet ...