• 【hdu4267 A Simple Problem with Integers】 线段树之区间操作


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4267

    题目大意:给你一列数区间范围为[1,n],区间每个数有一个对应值a[i]。接下来有Q个操作

    操作1: "1 a b k c", 区间[a,b]内满足条件(i-a)%k==0的数值a[i]加c。

    操作2:“2 a” ,输出a[i]的值。

    解题思路:这题蛋都碎成渣渣了,RE几次,MLE无数次。

    1、按线段树建树情况可推出,即使成为完全平衡树开也只有2*n-1个节点,开2*n的大小完全没问题啊,但它就是RE,不解。

    2、这题我的初始化开始没有建build()函数,而是直接对flag[][]初始化,这里MLE无数次,建树开build()函数成段成段初始化就过了,蛋都碎成渣渣了。

    说说解题思路吧,重点在(i-a)%k==0,这样的i是断开的,无法成段操作,傻×才去暴力。注意到k比较小,枚举k以及余数的组合,k=1有1种,k=2有2种,……k=10有10种,所以总共有(1+2+3....+10=55种组合),我们将每种组合压缩成一个状态。

    建树操作: 成段初始化,不然MLE。

    更新操作: 当查询到对应区间[tl,tr],对应的组合状态flag[u][mo]加上c,返回。

    查询操作:对x路过的区间进行操作,当x与k(1<=k<=10)对应的余数值这个状态有值时,加上这个值。

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6 
     7 #define lz 2*u,l,mid
     8 #define rz 2*u+1,mid+1,r
     9 const int maxn=500005;
    10 int flag[4*maxn][55], val[maxn];
    11 
    12 void build(int u, int l, int r)  ///开始没这样建树初始化,而是直接memset(flag,0,sizeof(flag)),一直MLE,蛋都碎成渣渣了
    13 {
    14     memset(flag[u],0,sizeof(flag[u]));
    15     if(l==r) return ;
    16     int mid=(l+r)>>1;
    17     build(lz);
    18     build(rz);
    19 }
    20 
    21 void Update(int u, int l, int r, int tl, int tr, int mo, int k, int c)
    22 {
    23     if(tl<=l&&r<=tr)
    24     {
    25         for(int i=1; i<k; i++) mo+=i;
    26         flag[u][mo]+=c;
    27         return ;
    28     }
    29     int mid=(l+r)>>1;
    30     if(tr<=mid) Update(lz,tl,tr,mo,k,c);
    31     else if(tl>mid) Update(rz,tl,tr,mo,k,c);
    32     else
    33     {
    34         Update(lz,tl,mid,mo,k,c);
    35         Update(rz,mid+1,tr,mo,k,c);
    36     }
    37 }
    38 
    39 void Query(int u, int l, int r, int x, int &res)
    40 {
    41     for(int i=1; i<=10; i++)
    42     {
    43         int mo=x%i;
    44         for(int j=1; j<i; j++) mo+=j;
    45         res+=flag[u][mo];
    46     }
    47     if(l==r) return ;
    48     int mid=(l+r)>>1;
    49     if(x<=mid) Query(lz,x,res);
    50     else Query(rz,x,res);
    51 }
    52 
    53 int main()
    54 {
    55     int n, Q;
    56     while(~scanf("%d",&n))
    57     {
    58         for(int i=1; i<=n; i++) scanf("%d",val+i);
    59         int op, a, b, k, c;
    60         build(1,1,n);
    61         scanf("%d",&Q);
    62         while(Q--)
    63         {
    64             scanf("%d",&op);
    65             if(op==1)
    66             {
    67                 scanf("%d%d%d%d",&a,&b,&k,&c);
    68                 Update(1,1,n,a,b,a%k,k,c);
    69             }
    70             else
    71             {
    72                 scanf("%d",&a);
    73                 int res=0;
    74                 Query(1,1,n,a,res);
    75                 printf("%d\n",res+val[a]);
    76             }
    77         }
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    hashCode() vs equals() vs ==
    DELPHI 关于 Style 的几点
    定制Mybatis拦截器开发【含源码追溯】
    Kubernetes 安装手册(非高可用版)
    查询组织数据,根据父级编号形成组织树
    Win10使用Virtual Box和Vagrant搭建CentOS7虚拟机集群环境sunziren
    FastDFS安装和简介详细总结
    Docker从入门到精通
    三种移除list中的元素(可靠)
    请求响应浏览器时乱码
  • 原文地址:https://www.cnblogs.com/kane0526/p/3034711.html
Copyright © 2020-2023  润新知