线段树区间更新 费马小定理|魔豆传奇

程序设计:魔豆传奇
《魔豆传奇》是2004年的一部动画片。里面有很多奇怪的魔豆,具有奇特且强大的能力。
偶然间,蒜头君获得了一排已经发芽的魔豆,每株的最初高度为ai 。
蒜头君每天都会选择对一段区间的魔豆浇水,或查看一段区间魔豆的高度和。
魔豆每一次被浇水,其高度会变为之前高度的立方。
也就是说,蒜头君有两种操作:
1.使序列中下标在区间[L,R] 中的每个数变成自己的立方。
2.查询序列中下标在区间[L,R]中的数值和。
由于魔豆高度过大,查询时你需要输出数值和对1046513837 取模的结果。

题解:


线段树做法:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define LL long long
#define mod 1046513837

int n, m;
int a[100010], f[400010][30], tmp[30], lazy[400010];

//更新lazy标记
void push(int t)
{
    if (!lazy[t]) return;
    //下放标记
    lazy[t + t] = (lazy[t + t] + lazy[t]) % 28;
    lazy[t + t + 1] = (lazy[t + t + 1] + lazy[t]) % 28;
    //更新子区间2*t
    for (int i = 0; i < 28; ++i) tmp[i] = f[t + t][i];
    for (int i = 0; i < 28; ++i) f[t + t][i] = tmp[(i + lazy[t]) % 28];
    //更新子区间2*t+1
    for (int i = 0; i < 28; ++i) tmp[i] = f[t + t + 1][i];
    for (int i = 0; i < 28; ++i) f[t + t + 1][i] = tmp[(i + lazy[t]) % 28];
    lazy[t]=0;
}

void build(int t, int l, int r)
{
    if (l == r)
    {
        f[t][0] = a[l];//初始值 就是a数组的值
        for (int i = 1; i < 28; ++i)
        {
            f[t][i] = (LL)f[t][i - 1] * f[t][i - 1] % mod * f[t][i - 1] % mod; //f数组第二维 表示第i个3次方  可以从0个3次方初始值递推
        }
        return;
    }
    int mid = (l + r) / 2;
    build(t + t, l, mid);
    build(t + t + 1, mid + 1, r);
    for (int i = 0; i < 28; ++i) f[t][i] = (f[t + t][i] + f[t + t + 1][i]) % mod; //当前区间f数组 f[t][i]等于 两个子区间的和
}

//更新
void modify(int t, int l, int r, int x, int y)
{
    if (x <= l && r <= y)
    {
        lazy[t] = (lazy[t] + 1) % 28;
        for(int i = 0; i < 28; ++i) tmp[i] = f[t][i];
        for(int i = 0; i < 28; ++i) f[t][i] = tmp[(i + 1) % 28];
        return;
    }
    push(t);
    int mid = (l + r) / 2, res = 0;
    if (x <= mid) modify(t + t, l, mid, x, y);
    if (y > mid) modify(t + t + 1, mid + 1, r, x, y);
    for(int i = 0; i < 28; ++i) f[t][i] = (f[t + t][i] + f[t + t + 1][i]) % mod;
}

int sum(int t, int l, int r, int x, int y)
{
    if (x <= l && r <= y) return f[t][0];
    push(t);//求t结点时 下放更新 t的值
    int mid = (l + r) / 2, res = 0;
    if (x <= mid) res += sum(t + t, l, mid, x, y);
    if (y > mid) res += sum(t + t + 1, mid + 1, r, x, y);
    for (int i = 0; i < 28; ++i) f[t][i] = (f[t + t][i] + f[t + t + 1][i]) % mod;
    return res % mod;
}

int main()
{
    memset(lazy, 0, sizeof(lazy));
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    build(1, 1, n);
    for (int i = 1; i <= m; ++i)
    {
        int o, l, r;
        scanf("%d%d%d", &o, &l, &r);
        if (o == 2) printf("%d\n", sum(1, 1, n, l, r));
        else modify(1, 1, n, l, r);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/fisherss/p/10890578.html

时间: 2024-10-12 12:16:36

线段树区间更新 费马小定理|魔豆传奇的相关文章

2014多校第一场 I 题 || HDU 4869 Turn the pokers(费马小定理+快速幂模)

题目链接 题意 : m张牌,可以翻n次,每次翻xi张牌,问最后能得到多少种形态. 思路 :0定义为反面,1定义为正面,(一开始都是反), 对于每次翻牌操作,我们定义两个边界lb,rb,代表每次中1最少时最少的个数,rb代表1最多时的个数.一张牌翻两次和两张牌翻一次 得到的奇偶性相同,所以结果中lb和最多的rb的奇偶性相同.如果找到了lb和rb,那么,介于这两个数之间且与这两个数奇偶性相同的数均可取到,然后在这个区间内求组合数相加(若lb=3,rb=7,则3,5,7这些情况都能取到,也就是说最后的

hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

#1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们可以化身上帝模式,买卖房产. 在这个游戏里,会不断的发生如下两种事件:一种是房屋自发的涨价或者降价,而另一种是政府有关部门针对房价的硬性调控.房价的变化自然影响到小Hi和小Ho的决策,所以他们希望能够知道任意时刻某个街道中所有房屋的房价总和是多少——但是很不幸的,游戏本身并不提供这样的计算.不过这难

CSU1516矩阵快速幂+费马小定理

通过这个题真的学到了不少东西,最起码矩阵快速幂算是入门了,普通快速幂也彻底明白了(以前都是打模板),了解了费马小定理 关键点 求(a^fib[b])%p 的值其中p是素数,0<a<p, b在int范围内 先假设fib[b]>p-1 那么上式 (a^fib[b])%p = (a^(p-1)*a^(p-1)*....*a^(p-1)*a^m)%p (这里 m = fib[b]%(p-1)) 由于p是素数且a<p那么gcd(a,p)=1,所以由费小可得(a^(p-1))%p=1 那上式就

Uva 1232 - SKYLINE ( 线段树 + 区间更新 )

Uva 1232 SKYLINE (线段树 + 区间更新) 题意: 按照顺序在地面上建造放在,每个房子的高度为h,操作 l r h 表示 在(l,r] 区间建立一个高度为h的房子.统计每次建立完房子之后的overlap值之和 overlap值表示[ 修完一座房子之后,统计它在多长的部分是最高的(可以和其他房子并列高) ]如样例图,按照灰.黒.白的顺序建立房子 ans = (11-5) + (5-1) + (5-3) + (13-11) = 6 + 4 + 4 = 14 分析: 一开始一直想不明白

线段树 区间更新

poj3468 A Simple Problem with Integers ( m - ( m >> 1 ) )这里跪了几发.. - 的优先级大于 >> 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<string> 6 #include<queue> 7 #include

hdu 4869 Turn the pokers(组合数+费马小定理)

Problem Description During summer vacation,Alice stay at home for a long time, with nothing to do. She went out and bought m pokers, tending to play poker. But she hated the traditional gameplay. She wants to change. She puts these pokers face down,

hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)

#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了小Ho: 假设货架上从左到右摆放了N种商品,并且依次标号为1到N,其中标号为i的商品的价格为Pi.小Hi的每次操作分为两种可能,第一种是修改价格——小Hi给出一段区间[L, R]和一个新的价格NewP,所有标号在这段区间中的商品的价格都变成NewP.第二种操作是询问——小Hi给出一段

hdu--5023 A Corrupt Mayor&#39;s Performance Art(线段树+区间更新+位运算)

Description Corrupt governors always find ways to get dirty money. Paint something, then sell the worthless painting at a high price to someone who wants to bribe him/her on an auction, this seemed a safe way for mayor X to make money. Because a lot

HDU4869:Turn the pokers(费马小定理+高速幂)

Problem Description During summer vacation,Alice stay at home for a long time, with nothing to do. She went out and bought m pokers, tending to play poker. But she hated the traditional gameplay. She wants to change. She puts these pokers face down,