zoukankan      html  css  js  c++  java
  • codechef FNCS

    题意:一个数列a,若干个函数,每个函数j=sigma(a[i]),l[j]<=i<=r[j]。

    op1:修改数列a中x位置元素为y。op2:求L~R的函数和。n<=1e5。

    标程:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned long long ll;
     4 int read()
     5 {
     6    int x=0,f=1;char ch=getchar();
     7    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
     8    while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
     9    return x*f;
    10 }
    11 const int N=100005;
    12 int n,blo,a[N],l[N],r[N],b[320][N],q,x,y,op;
    13 ll sum[N],k1[N],k2[N],s[N];
    14 
    15 int trans1(int x){return x>blo*blo?blo:(x-1)/blo+1;}//所在块 
    16 int trans2(int x){int t=trans1(x);return t==blo?n:t*blo;}//所在块的右端点 
    17 
    18 void modi(int pos,int x)
    19 {
    20     for (int i=trans1(pos);i<=blo;i++) k1[i]+=x;
    21     for (int i=pos,t=trans2(pos);i<=t;i++) k2[i]+=x;
    22 }
    23 
    24 ll qry(int x){
    25     return s[x]+k1[trans1(x)-1]+k2[x];
    26 }
    27 
    28 ll calc(int x)
    29 {
    30     ll res=0;int id=trans1(x);
    31     for (int i=1;i<id;i++) res+=sum[i];
    32     for (int i=(id-1)*blo+1;i<=x;i++) res+=qry(r[i])-qry(l[i]-1);
    33     return res;
    34 }
    35 
    36 int main()
    37 {
    38     n=read();blo=(int)sqrt(n);
    39     for (int i=1;i<=n;i++) a[i]=read(),s[i]=(ll)s[i-1]+a[i];
    40     for (int i=1;i<=n;i++) l[i]=read(),r[i]=read();
    41     
    42    for (int i=1;i<=blo;i++)
    43    {
    44        int bl=(i-1)*blo+1,br=(i==blo)?n:i*blo;
    45        for (int j=bl;j<=br;j++) b[i][l[j]]++,b[i][r[j]+1]--;
    46        for (int j=1;j<=n;j++) b[i][j]+=b[i][j-1];
    47        for (int j=1;j<=n;j++) sum[i]+=(ll)b[i][j]*a[j];
    48     }
    49     
    50     q=read();
    51     while (q--)
    52     {
    53         op=read();x=read();y=read();
    54         if (op==1)
    55         {
    56             for (int i=1;i<=blo;i++) sum[i]+=(ll)b[i][x]*(y-a[x]);
    57          modi(x,y-a[x]);a[x]=y;
    58         }else printf("%llu
    ",calc(y)-calc(x-1));
    59     }
    60    return 0;
    61 }

    易错点:1.没有开ll挂了90分。不要以为ll是小问题。

    2.还要unsigned long long。

    3.注意左右端点,尤其是最后一块。写个trans函数比较直观。

    题解:分块+块链

    对函数进行分块,每一块维护每个数列元素的需统计次数以及sum。(每个元素的出现次数可以用差分+前缀和)。

    查询的时候整块暴力统计sum,零碎的直接统计即可。

    零碎的统计要支持修改和区间查询,树状数组(插入查询O(logn)),块链(插入O(sqrt(n)),查询O(1))都行。块链,就是对原数列分块,统计大块的前缀和,对于每个块统计内部元素的前缀和。

  • 相关阅读:
    CSS系列:长度单位&字体大小的关系em rem px
    CSS兼容性
    html5+css3
    将url的查询参数解析成字典对象
    SQL阻止保存要求重新创建表的更改 在哪里设置
    Jquery&JS简单选项卡
    块级&行内(内联)元素
    时间
    PHP 二维数组根据某个字段排序
    php 操作数组 (合并,拆分,追加,查找,删除等)
  • 原文地址:https://www.cnblogs.com/Scx117/p/9080957.html
Copyright © 2011-2022 走看看