• hdu 4267 多维树状数组


    题意:有一个序列

    "1 a b k c" means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
    "2 a" means querying the value of Aa. (1 <= a <= N)

    分析转自:http://www.cnblogs.com/Griselda/archive/2012/09/15/2686133.html

    感觉是树状数组了

    但是 树状数组是单点更新 而题目要求是在a b 内每隔 k 个数更新..

    如果用for循环对a b 内每隔 k 个位置的数更新就会很费时间..

    所以有一个方法就是 按 k 值 i%k 值还有 i/k+1 值把每隔 k 个位置的值都分组..即按 k 值和 i%k 值建树状数组 

    到时候维护其中一棵 树状数组就好了..

     

    维护的方法是在c[ k ][a%k][(i-a)/k+1] + 1 在c[ k ][a % k ][ (a/k) + (b-a)/k + 2 ] - 1..

     

    关于建成的树状数组..

    更新时有55种情况
    1,2,3,4,5......
    1,3,5,7,9......
    2,4,6,8,10....
    1,4,7,10,13...
    2,5,9,12,15...
    3,6,10,13,16...
    .
    .
    .
    10,20,30,40,50...

    所以用55个树状数组.

    建出来的树并不是普通的1,2,3,4,这样的,而是有着间隔的,其实也就是建造了许多树状数组

     1 #include<stdio.h>
     2 
     3 #include<queue>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<string.h>
     7 const int MAXN=50020;
     8 
     9 
    10 int c[12][12][MAXN];
    11 int n;
    12 
    13 int lowbit(int x)
    14 {
    15     return x&(-x);
    16 }
    17 
    18 void update(int t1,int t2,int i,int val)
    19 {
    20     while(i<=n)
    21     {
    22         c[t1][t2][i]+=val;
    23         i+=lowbit(i);
    24     }
    25 
    26 }
    27 int sum(int t1,int t2,int i)
    28 {
    29 
    30     int s=0;
    31     while(i>0)
    32     {
    33         s+=c[t1][t2][i];
    34         i-=lowbit(i);
    35     }
    36     return s;
    37 }
    38 int num[MAXN];
    39 int main()
    40 {
    41     #ifndef ONLINE_JUDGE
    42     freopen("1.in","r",stdin);
    43     #endif
    44     int m;
    45     while(scanf("%d",&n)!=EOF)
    46     {
    47         for(int i=0;i<n;i++)scanf("%d",&num[i]);
    48         for(int i=0;i<12;i++)
    49           for(int j=0;j<12;j++)
    50             for(int k=0;k<MAXN;k++)
    51               c[i][j][k]=0;
    52         scanf("%d",&m);
    53         int a,b,k,q;
    54         int t;
    55         while(m--)
    56         {
    57             scanf("%d",&t);
    58             if(t==1)
    59             {
    60                 scanf("%d%d%d%d",&a,&b,&k,&q);
    61                 a--;
    62                 b--;
    63                 int num=(b-a)/k;    
    64                 int s=a%k-1;
    65                 update(k,s,a/k+1,q);    //s是该数组的开头数字,a/k+1是结尾的数字
    66                 update(k,s,a/k+num+2,-q);
    67             }
    68             else
    69             {
    70                 scanf("%d",&a);
    71                 a--;
    72                 int ss=num[a];
    73                 for(int i=1;i<=10;i++)
    74                 {
    75                     ss+=sum(i,a%i-1,a/i+1);
    76                 }
    77                 printf("%d
    ",ss);
    78             }
    79         }
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    GTK+中的树状列表构件(GtkTreeView)
    [TOP]疯狂的投资
    多线程模式之MasterWorker模式
    一年读书总结
    Microsoft Visual Studio正忙解决办法
    使用vs自带的性能诊断工具
    C#中的扩展方法
    从委托、匿名方法到Lambda
    c#中的事件
    sqlserver中创建包含事务的存储过程
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4343583.html
Copyright © 2020-2023  润新知