zoukankan      html  css  js  c++  java
  • hdu 4267 A Simple Problem with Integers (线段树)

     转自:

    题目:给出n个数,每次将一段区间内满足(i-l)%k==0  (r>=i>=l) 的数ai增加c

    http://acm.hdu.edu.cn/showproblem.php?pid=4267 

    比较容易往线段树上想的。但是由于更新的是一些离散的点,比较麻烦

    可以考虑这些点的共性,总是隔几个,更新一个,那窝萌把区间内的数关于k的余数分组

    这样每次更新的都是其中的一组,而且是连续的。

    由于 K比较小,这是本题的突破口,那么关于k的余数情况,最多只有55种。

    即如果k=1,则分为1组,k=2分为2组……

    一开始傻叉了打算维护55棵线段树,其实也是可以的,更新只需要1棵,查询是10棵,还是可以接受的。

    不过只需要在线段树结点维护这55种情况即可。

    不过内存比较紧,要把所有的情况压缩一下,不能开10*10的空间。

    同样更新只需要一个,最终统计的话,需要遍历所有的K,也就是最多是10.


      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<set>
      7 #include<map>
      8 #include<queue>
      9 #include<vector>
     10 #include<string>
     11 #define Min(a,b) a<b?a:b
     12 #define Max(a,b) a>b?a:b
     13 #define CL(a,num) memset(a,num,sizeof(a));
     14 #define eps  1e-12
     15 #define inf 100000000
     16 #define mx  10
     17 
     18 const double pi  = acos(-1.0);
     19 const int  maxn = 50100;
     20 typedef   __int64  ll;
     21 using namespace std;
     22 struct node
     23 {
     24     int l;
     25     int r;
     26     int w;
     27     int add[55] ;
     28 }p[maxn *4];
     29 int a[maxn], b[11][11];
     30 void build(int x,int l,int r)
     31 {
     32     p[x].l = l;
     33     p[x].r = r;
     34     CL(p[x].add,0);
     35     if(l == r)
     36     {
     37         p[x].w = a[l];
     38         return ;
     39     }
     40     int mid = (l + r)>>1;
     41     build(2*x,l,mid);
     42     build(2*x+1,mid+ 1,r);
     43 
     44     p[x].w = p[x*2].w + p[x*2+1].w ;
     45 }
     46 void push_down(int x)
     47 {
     48     if(p[x].w)
     49     {
     50         p[x*2].w +=p[x].w;
     51         p[x*2+1].w +=p[x].w;
     52         p[x].w = 0;
     53         for(int i =0  ; i < 55;i++)
     54         {
     55             p[x*2].add[i] +=p[x].add[i];
     56             p[x*2+1].add[i]+=p[x].add[i];
     57             p[x].add[i] = 0;
     58         }
     59     }
     60 }
     61 void update(int x,int l,int r,int num,int i,int j)
     62 {
     63     if(p[x].l == l &&p[x].r == r)
     64     {
     65         p[x].w +=num;
     66         p[x].add[b[i][j]]+=num ;
     67         return ;
     68     }
     69     push_down(x);
     70     int mid = (p[x].l + p[x].r)>>1 ;
     71     if(l > mid)update(x*2+1,l,r,num,i,j);
     72     else
     73     {
     74         if(r<=mid)update(x*2,l,r,num,i,j);
     75         else
     76         {
     77             update(x*2,l,mid,num,i,j);
     78             update(x*2+1,mid+1,r,num,i,j);
     79         }
     80     }
     81 }
     82 int qury(int x,int pos)
     83 {
     84     if(p[x].l == pos&&p[x].r == pos)
     85     {
     86         int tmp = 0;
     87         for(int i = 1 ; i <= 10 ;i++)
     88         {
     89             tmp+=p[x].add[b[i][pos%i]];
     90         }
     91         return tmp + a[pos] ;
     92     }
     93     push_down(x) ;
     94     int mid = (p[x].l + p[x].r)>> 1;
     95     if(pos <= mid)  return   qury(2*x,pos);
     96     else
     97     {
     98         return qury(x*2+1,pos);
     99     }
    100 }
    101 int main()
    102 {
    103     freopen("data.txt","r",stdin);
    104     int  n,s,e,k,c,i,j,q,ty;
    105     int cnt = 0;
    106     for(i = 1; i<= 10;i++)
    107     {
    108         for(j = 0;j< i;j++)
    109           b[i][j] = cnt++;//由于 内存 卡的紧 ,所以 这样编号 ,不能开 10*10 的
    110     }
    111     while(scanf("%d",&n)!=EOF)
    112     {
    113         for(i =1  ; i <=n;i++)
    114         {
    115             scanf("%d",&a[i]) ;
    116         }
    117         build(1,1,n);
    118         scanf("%d",&q);
    119         while(q--)
    120         {
    121             scanf("%d",&ty);
    122             if(ty==1)
    123             {
    124                 scanf("%d%d%d%d",&s,&e,&k,&c);
    125                 update(1,s,e,c,k,s%k);//这里为什么是 s% k 呢 ,因为 : (i- s)%k = (i%k - s%k + k)%k = 0 的话 ,i%k 应该  = s%k ;
    126             }
    127             else
    128             {
    129                 int  pos;
    130                 scanf("%d",&pos);
    131                  int ans = qury(1,pos);
    132                  printf("%d\n",ans);
    133             }
    134 
    135         }
    136     }
    137 }
  • 相关阅读:
    springboot2.04+mybatis-plus+swagger2+CodeGenerator
    1.Jenkins 在windows下的安装与配置
    .Net Core Linux centos7行—vscode开发,linux部署运行
    .Net Core Linux centos7行—安装nginx,运行静态网站
    .Net Core Linux centos7行—hyper-v安装linux系统和.net core sdk
    扩展htmlhelper.DropDownListFor 支持list数据源和option增加属性
    SignalR主动通知订阅者示例
    asp.net mvc HandleErrorAttribute 异常错误处理 无效!
    Microsoft.AspNet.Identity 自定义使用现有的表—登录实现
    asp.net mvc输出自定义404等错误页面,非302跳转。
  • 原文地址:https://www.cnblogs.com/acSzz/p/2679421.html
Copyright © 2011-2022 走看看