Array's Hash【差分】

题目描述:原题链接

在这里插入图片描述

思路:

首先是差的形式,并且对区间进行了多次修改,不难想到差分。以元素个数为5为例,经推导结果为 a5-{a4-[a3-(a2-a1)]} ,所以要定义特殊的差分,每一个位置存的是当前数和(前一个数和再前一个数的差)的差,这样结果就可以简化为b[n]。首先可以发现如果修改区间的长度是偶数,那么它们之间就会把增量抵消,从而对结果无影响。当区间长度为奇数时要分情况讨论。当数组长度为奇数时,首先对上式做变形可以得到 a5-a4+a3-a2+a1 ,如果区间右端点为奇数最后会多加一个增量不能抵消掉,所以结果是b[n]+w,若是偶数则会多减一个增量,所以结果是b[n]-w。当数组长度为偶数时正好相反。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <iomanip>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=500010;

int n,q,l,r,w,a[N];
long long d[N];
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        d[i]=a[i]-d[i-1];
    }
    scanf("%d",&q);
    while (q--)
    {
        scanf("%d%d%d",&l,&r,&w);
        if (n%2==1)
        {
            if (r%2==0 && (r-l+1)%2==1) d[n]-=w;
            if (r%2==1 && (r-l+1)%2==1) d[n]+=w;
        }
        if (n%2==0)
        {
            if (r%2==0 && (r-l+1)%2==1) d[n]+=w;
            if (r%2==1 && (r-l+1)%2==1) d[n]-=w;
        }
        printf("%lld\n",d[n]);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Jenkins Hash 是由 Bob Jenkins 设计的一种哈希算法,它可以将任意长度的输入数据映射为一个 32 位的哈希值。Jenkins Hash 的实现非常简单,具有良好的散列性和高效性,被广泛应用于各种编程语言中。 Jenkins Hash 的核心思想是将输入数据分成若干个 4 字节的块,对每个块进行一系列简单的位运算和乘法运算,最后将结果累加起来得到哈希值。具体来说,Jenkins Hash 的伪代码如下: ``` uint32_t jenkins_hash(const void* key, size_t length, uint32_t initval) { uint32_t a, b, c, len; const uint8_t* data = (const uint8_t*)key; len = length; a = b = 0x9e3779b9; c = initval; while (len >= 12) { a += (data[0] + ((uint32_t)data[1] << 8) + ((uint32_t)data[2] << 16) + ((uint32_t)data[3] << 24)); b += (data[4] + ((uint32_t)data[5] << 8) + ((uint32_t)data[6] << 16) + ((uint32_t)data[7] << 24)); c += (data[8] + ((uint32_t)data[9] << 8) + ((uint32_t)data[10] << 16) + ((uint32_t)data[11] << 24)); a -= b; a -= c; a ^= (c >> 13); b -= c; b -= a; b ^= (a << 8); c -= a; c -= b; c ^= (b >> 13); data += 12; len -= 12; } c += length; switch (len) { case 11: c += ((uint32_t)data[10] << 24); case 10: c += ((uint32_t)data[9] << 16); case 9: c += ((uint32_t)data[8] << 8); case 8: b += ((uint32_t)data[7] << 24); case 7: b += ((uint32_t)data[6] << 16); case 6: b += ((uint32_t)data[5] << 8); case 5: b += data[4]; case 4: a += ((uint32_t)data[3] << 24); case 3: a += ((uint32_t)data[2] << 16); case 2: a += ((uint32_t)data[1] << 8); case 1: a += data[0]; } a -= b; a -= c; a ^= (c >> 13); b -= c; b -= a; b ^= (a << 8); c -= a; c -= b; c ^= (b >> 13); return c; } ``` 其中,`key` 是输入数据的指针,`length` 是输入数据的长度,`initval` 是初始哈希值。该函数使用三个 32 位的变量 `a`、`b` 和 `c` 来分别保存计算过程中的中间值,使用 `len` 来追踪剩余的数据长度,使用 `data` 来追踪当前处理的输入数据指针。最后,将 `c` 作为哈希值返回。 Jenkins Hash 的优点有: - 易于实现和快速计算。 - 具有良好的散列性能,能够避免哈希冲突,并产生良好的哈希分布。 - 支持增量哈希计算,可以在处理大型数据流时有效地避免内存问题。 由于 Jenkins Hash 的实现简单且性能优秀,因此它被广泛用于各种哈希表、数据结构、散列算法等场合。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值