zoukankan      html  css  js  c++  java
  • CodeChef FNCS (分块+树状数组)

    题目:https://www.codechef.com/problems/FNCS

    题解:

      我们知道要求区间和的时候,我们用前缀和去优化。这里也是一样,我们要求第 l 个函数到第 r 个函数 [l, r] 的函数和,那么我们可以用 sum[r] - sum[l-1] 来求得。

      由于这个数据量有点大,所以我们将函数分块。

      例如样例:

        1 3    有5个函数,那么我们分成3块。{ [1 3] , [2 5] }, { [4 5], [3 5] }, { [1 2] }。每一块对应都有一个sum ,这时如果我们要求前3个函数的和,就可以 (第一块的sum + 第3个函数的和)
        2 5    在一个块内暴力的复杂度是O(sqrt(n))
        4 5
        3 5    还有就是在处理块内函数总sum 记录下每一个a[i] 对应的权值。比如在第一块中 1 2 2 1 1 分别是a1~a5对这一块sum 的贡献。 
        1 2

       更新的时候就维护一下就可以了

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <string>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include <vector>
      8 #include <queue>
      9 #include <map>
     10 #include <stack>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 typedef unsigned long long uLL;
     15 #define ms(a, b) memset(a, b, sizeof(a))
     16 #define pb push_back
     17 #define mp make_pair
     18 const LL INF = 0x7fffffff;
     19 const int inf = 0x3f3f3f3f;
     20 const int mod = 1e9+7;
     21 const int maxn = 100000+10;
     22 const int maxm = 1000000+10;
     23 int a[maxn], l[maxn], r[maxn], Add[maxn];
     24 int unit, num, n;
     25 int cnt[1000][maxn];//记录在第i块,j值的权
     26 uLL sum[1000];//块的sum
     27 uLL BIT_SUM[maxn];
     28 int low_bit(int x)
     29 {
     30     return x&-x;
     31 }
     32 uLL BIT_sum(int x)
     33 {
     34     uLL ret = 0;
     35     while(x>0){
     36         ret += 1uLL*BIT_SUM[x]; x -= low_bit(x);
     37     }
     38     return ret;
     39 }
     40 void add(int x, int d)
     41 {
     42     while(x<=n){
     43         BIT_SUM[x] += d; x+=low_bit(x);
     44     }
     45 }
     46 uLL query(int x)
     47 {
     48     return 1uLL*BIT_sum(x);
     49 }
     50 uLL Query(int x)
     51 {
     52     int end_unit = x/unit + 1;
     53     LL ans = 0;
     54     for(int i = 1;i<end_unit;i++)
     55         ans += sum[i];
     56     for(int i = (end_unit-1)*unit+1;i<=x;i++)
     57         ans += query(r[i]) - query(l[i]-1);
     58     return ans;
     59 }
     60 void init()
     61 {
     62     ms(BIT_SUM, 0);
     63     ms(sum, 0);
     64     ms(cnt, 0);
     65 }
     66 int main() {
     67 #ifdef LOCAL
     68     freopen("input.txt", "r", stdin);
     69 //        freopen("output.txt", "w", stdout);
     70 #endif
     71 //    ios::sync_with_stdio(0);
     72 //    cin.tie(0);
     73     init();
     74     scanf("%d", &n);
     75     for(int i = 1;i<=n;i++){
     76         scanf("%d", &a[i]);
     77         add(i, a[i]);
     78     }
     79     for(int i = 1;i<=n;i++)  scanf("%d%d", &l[i], &r[i]);
     80     unit = (int)sqrt(n);//块的大小
     81     num = (n-1)/unit+1;//块的数量
     82     for(int i = 1;i<=num;i++){
     83         int begin_f = (i-1)*unit+1;//这一块的开始函数
     84         int end_f = begin_f + unit - 1;//结束函数
     85         ms(Add,0);
     86         for(int j = begin_f;j<=end_f&&j<=n;j++){
     87             Add[l[j]]++;Add[r[j]+1]--;
     88         }
     89         int add = 0;
     90         for(int j = 1;j<=n;j++){
     91             add += Add[j];
     92             cnt[i][j] += add;
     93         }
     94         for(int j = 1;j<=n;j++)
     95             sum[i] += 1uLL * a[j] * cnt[i][j];
     96 //        for(int j = 1;j<=n;j++)
     97 //            cout << cnt[i][j] <<" ";cout << endl;
     98 //        cout << sum[i] << endl;
     99     }
    100     int q;scanf("%d", &q);
    101     while(q--){
    102         int op;scanf("%d", &op);
    103         if(op==1){
    104             int x, y;scanf("%d%d", &x, &y);
    105             for(int i = 1;i<=num;i++)
    106                 sum[i] -= 1uLL * a[x] * cnt[i][x];
    107             add(x, y-a[x]);
    108             a[x] = y;
    109             for(int i = 1;i<=num;i++)
    110                 sum[i] += 1uLL * a[x] * cnt[i][x];
    111         }else{
    112             int x, y;
    113             scanf("%d%d", &x, &y);
    114             uLL ans = Query(y) - Query(x-1);
    115             printf("%llu
    ", ans);
    116         }
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    将博客搬至CSDN
    机器学习中的超参数(Hyperparameters in machine learning)
    《机器学习笔记》-环境配置
    采用KNN算法实现一个简单的推荐系统
    推荐系统介绍:(协同过滤)—Intro to Recommender Systems: Collaborative Filtering
    推荐系统中TopN与kNN的区别
    采用KNN算法实现一个简单的推荐系统
    k-medoids与k-Means聚类算法的异同
    使用Spring Initializer快速创建Spring Boot项目
    Spring 自动注入
  • 原文地址:https://www.cnblogs.com/denghaiquan/p/7236702.html
Copyright © 2011-2022 走看看