zoukankan      html  css  js  c++  java
  • noip模拟赛 Nephren Ruq Insania

    题目背景

    大样例下发链接: https://pan.baidu.com/s/1nuVpRS1 密码: sfxg

    注意:本题大样例4的输出文件修改为 https://pan.baidu.com/s/1bUWuZW

    奈芙莲·卢可·印萨尼亚(Nephren-Ruq-Insania)

    同为妖精仓库的成体妖精兵,天赋不如珂朵莉一般,只是一个平凡的妖精.

    睡觉时如同毯子一般在威廉身上为其保暖。习惯于粘着威廉,在梦境中与艾尔梅莉亚交谈时,自称就像是威廉的宠物一样。

    本题题面中含有大量的剧透,建议做题之前将这部番剧看完(

    题目描述

    她只是一个非常普通的黄金妖精。

    在援救打捞队的作战中,他们不幸与(几乎是所有的)第六兽相遇了。

    此时的珂朵莉因为接触到星神艾露可本体,正处于昏迷之中。而威廉也无法离开珂朵莉。

    默默守护在房间外的她,提起圣剑,走向了战场。

    作为本身天赋只是一般的妖精少女,她难以对抗无数倍于自己的六号兽。

    没有多久,她开始体力不支。

    终于,在源源不断的六号兽面前,她难以抵挡了……

    终于,由于魔力过度激发,她已经处在了魔力失控的边缘……

    ”威廉,拯救,是我们黄金妖精的使命。“

    ”况且,威廉之前已经救过我们了。“

    ”所以,已经没有问题了。“

    威廉想要救下奈芙莲,但是他自己也已经处于崩溃的边缘。

    冥冥之中他想起了曾经学习过的一种魔法。在这最后一刻,或许已经是唯一的办法了。

    这种魔法操作的对象是一个咒语组成的序列,每一个单独的咒语拥有自己的法力值。

    威廉需要不断地按照之前的记忆,对某一段区间的法力值加上一个数,或者求出某一段区间的法咒共鸣。

    分析:这道题部分分还是比较多的.第一个数据点看起来数据非常小,但是3^3^3^3^3mod p会算不出来,因为次数很大,不能直接对次数取模.怎么将次数变小呢?欧拉定理! ,可以发现如果这道题就是不断地使用欧拉定理,直到φ(p)变成1或者计算完整个区间,这实际上就是一个递归的过程.用线段树进行区间修改,单点查询。

          有几个地方需要注意:

          1.如果区间[l,r]中第x位是1,那么[x,r]都不需要考虑了,因为1^n = 1.

          2.欧拉定理成立的条件是x >= φ(p),而由于忽略0和1的情况,2^2^2^2^2就足以满足数据范围了,所以暴力枚举5位乘起来看看是不是>=φ(p)就可以了.如果<φ(p)就可以直接算,而不需要欧拉定理了.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 500010;
    
    int n, m, prime[20000010], phi[20000010], cnt, flag[maxn];
    long long tag[maxn << 2], c[maxn << 2], a[maxn], L[maxn << 2], R[maxn << 2];
    bool vis[20000010];
    
    void init()
    {
        phi[1] = 1;
        for (int i = 2; i <= 20000000; i++)
        {
            if (!vis[i])
            {
                prime[++cnt] = i;
                phi[i] = i - 1;
            }
            for (int j = 1; j <= cnt; j++)
            {
                int t = i * prime[j];
                if (t > 20000000)
                    break;
                vis[t] = 1;
                if (i % prime[j] == 0)
                {
                    phi[t] = phi[i] * prime[j];
                    break;
                }
                phi[t] = phi[i] * (prime[j] - 1);
            }
        }
    }
    
    void pushup(int o)
    {
        c[o] = c[o * 2] + c[o * 2 + 1];
    }
    
    void pushdown(int o)
    {
        if (tag[o])
        {
            tag[o * 2] += tag[o];
            tag[o * 2 + 1] += tag[o];
            c[o * 2] += (R[o * 2] - L[o * 2] + 1) * tag[o];
            c[o * 2 + 1] += (R[o * 2 + 1] - L[o * 2 + 1] + 1) * tag[o];
        }
        tag[o] = 0;
    }
    
    void build(int o, int l, int r)
    {
        L[o] = l;
        R[o] = r;
        if (l == r)
        {
            c[o] = a[l];
            return;
        }
        int mid = (l + r) >> 1;
        build(o * 2, l, mid);
        build(o * 2 + 1, mid + 1, r);
        pushup(o);
    }
    
    void update(int o, int l, int r, int x, int y, int v)
    {
        if (x <= l && r <= y)
        {
            tag[o] += v;
            c[o] += v;
            return;
        }
        pushdown(o);
        int mid = (l + r) >> 1;
        if (x <= mid)
            update(o * 2, l, mid, x, y, v);
        if (y > mid)
            update(o * 2 + 1, mid + 1, r, x, y, v);
        pushup(o);
    }
    
    long long query(int o, int l, int r, int pos)
    {
        if (l == r)
            return c[o];
        pushdown(o);
        int mid = (l + r) >> 1;
        if (pos <= mid)
            return query(o * 2, l, mid, pos);
        else
            return query(o * 2 + 1, mid + 1, r, pos);
    }
    
    long long Cal(int q)
    {
        if (flag[q] == m)
            return a[q];
        flag[q] = m;
        return a[q] = query(1, 1, n, q);
    }
    
    long long qpow(long long a, long long b, long long mod)
    {
        a %= mod;
        long long res = 1;
        while (b)
        {
            if (b & 1)
                res = (res * a) % mod;
            a = (a * a) % mod;
            b >>= 1;
        }
        return res;
    }
    
    long long jisuan(int l, int r, int mod)
    {
        if (mod == 1)
            return 1;
        if (l == r)
        {
            long long t = Cal(l);
            if (t < mod)  //直接算
                return t % mod;
            else
                return (t % mod) + mod;
        }
        int minn = min(n, l + 5);
        for (int i = l + 1; i <= minn; i++)
            if (Cal(i) == 1)
            {
                minn = i;
                break;
            }
        long long p = Cal(minn), tot = 0;
        for (int i = minn - 1; i >= l + 1; i--)
        {
            tot = p;
            p = 1;
            while (tot--)
            {
                p *= Cal(i);
                if (p >= phi[mod])
                    return qpow(Cal(l) % mod, jisuan(l + 1, r, phi[mod]) + phi[mod], mod);
            }
        }
        return qpow(Cal(l) % mod, jisuan(l + 1, r, phi[mod]), mod);
    }
    
    int main()
    {
        memset(flag, -1, sizeof(flag));
        init();
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
            scanf("%lld", &a[i]);
        build(1, 1, n);
        while (m--)
        {
            int op, l, r, mod;
            scanf("%d%d%d%d", &op, &l, &r, &mod);
            if (op == 1)
                update(1, 1, n, l, r, mod);
            else
                printf("%lld
    ", jisuan(l, r, mod) % mod);
        }
    
        return 0;
    }
  • 相关阅读:
    深度学习遥感影像(哨兵2A/B)超分辨率
    基于Google Earth Engine的全国地表温度反演
    蚂蚁森林的树木长得如何了?遥感云计算告诉你!!
    基于单分类器的高分辨率遥感影像道路提取
    基于google earth engine 云计算平台的全国水体变化研究
    超大影像栅格转矢量快速实现
    大规模深度学习多通道遥感图像样本增强
    大规模遥感影像匀光匀色的一些思考
    基于深度学习的珠海一号高光谱影像云检测
    全自动多源遥感影像大气校正方法
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7707350.html
Copyright © 2011-2022 走看看