[CF633H] Fibonacci-ish II

Fibonacci-ish II の 传送门

多个区间和去重交给莫队。

用线段树维护 \(\begin{bmatrix}fib_{i-1} \times val, fib_i \times val \end{bmatrix}\)

具体和线段树的区间和差不多,上传时左右儿子矩阵相加,下传时左右儿子矩阵都乘上懒标记。

斐波那契数列下一项的矩阵是 \(\begin{bmatrix}0 & 1 \\1 & 1 \end{bmatrix}\),插入新数时区间乘这个矩阵就行。

区间除要用刚才矩阵的逆矩阵 \(\begin{bmatrix}-1 & 1 \\1 & 0 \end{bmatrix}\),现在就变成乘法了。

卡常小技巧:

unsigned short,矩阵乘法展开,离散化。

#include <bits/stdc++.h>
#define int unsigned short
#define ls p << 1
#define rs p << 1 | 1
#define Ad tr[p].ad
#define mid (l + r >> 1)
using namespace std;
inline signed read()
{signed f = 0, ans = 0;char c = getchar();while (!isdigit(c))f |= c == '-', c = getchar();while (isdigit(c))ans = (ans << 3) + (ans << 1) + c - 48, c = getchar();return f ? -ans : ans;
}
void write(int x)
{if (x < 0)putchar('-'), x = -x;if (x > 9)write(x / 10);putchar(x % 10 + '0');
}
const signed N = 3e4 + 5, M = N << 2;
signed a[N], b[N];
int n, m, sq, si, mod;
int fib[N], res[N], mp[N], id[N];
struct que
{int l, r, id;bool operator<(const que &x) const{if (l / sq != x.l / sq)return l < x.l;return l / sq & 1 ? r < x.r : r > x.r;}
} q[N];
template <typename T>
inline T Mod(T &&x) { return x >= mod ? x -= mod : x; }
struct Matrix
{int h, w, a[2][2];Matrix() : Matrix(1, 2) {}Matrix(int H, int W) : h(H), w(W){for (int i = 0; i < h; ++i)for (int j = 0; j < w; ++j)a[i][j] = 0;}Matrix(short id){if (id == 0)assert(0);else{h = w = 2;if (id > 0)a[0][1] = a[1][0] = a[1][1] = 1, a[0][0] = 0;elsea[1][0] = a[0][1] = 1, a[0][0] = mod - 1, a[1][1] = 0;}}Matrix operator+(const Matrix &rhs) const{Matrix ans(*this);Mod(ans.a[0][0] += rhs.a[0][0]);Mod(ans.a[0][1] += rhs.a[0][1]);return ans;}Matrix operator*(const Matrix &rhs) const{Matrix ans(h, rhs.w);if (h == 1 && w == 2){ans.a[0][0] = Mod(1 * a[0][0] * rhs.a[0][0] % mod + 1 * a[0][1] * rhs.a[1][0] % mod);ans.a[0][1] = Mod(1 * a[0][0] * rhs.a[0][1] % mod + 1 * a[0][1] * rhs.a[1][1] % mod);}else{ans.a[0][0] = Mod(1 * a[0][0] * rhs.a[0][0] % mod + 1 * a[0][1] * rhs.a[1][0] % mod);ans.a[0][1] = Mod(1 * a[0][0] * rhs.a[0][1] % mod + 1 * a[0][1] * rhs.a[1][1] % mod);ans.a[1][0] = Mod(1 * a[1][0] * rhs.a[0][0] % mod + 1 * a[1][1] * rhs.a[1][0] % mod);ans.a[1][1] = Mod(1 * a[1][0] * rhs.a[0][1] % mod + 1 * a[1][1] * rhs.a[1][1] % mod);}return ans;}
} u[N], ru[N];
struct Tree
{struct tree{Matrix v;int sum;short ad;} tr[M];void down(signed p){if (Ad > 0){tr[ls].v = tr[ls].v * u[Ad], tr[ls].ad += Ad;tr[rs].v = tr[rs].v * u[Ad], tr[rs].ad += Ad;Ad = 0;}else if (Ad < 0){tr[ls].v = tr[ls].v * ru[-Ad], tr[ls].ad += Ad;tr[rs].v = tr[rs].v * ru[-Ad], tr[rs].ad += Ad;Ad = 0;}}void update(int p) { tr[p].v = tr[ls].v + tr[rs].v; }void insert(int l, int r, int x, signed p, int rk){++tr[p].sum;if (l == r){tr[p].v = Matrix(1, 2);tr[p].v.a[0][0] = 1 * fib[rk - 1] * b[x] % mod;tr[p].v.a[0][1] = 1 * fib[rk] * b[x] % mod;return;}down(p);if (mid >= x)insert(l, mid, x, ls, rk);elseinsert(mid + 1, r, x, rs, rk);update(p);}void insert(int x, int rk) { insert(1, si, x, 1, rk); }void remove(int l, int r, int x, signed p){--tr[p].sum;if (l == r){tr[p].v = Matrix();return;}down(p);if (mid >= x)remove(l, mid, x, ls);elseremove(mid + 1, r, x, rs);update(p);}void remove(int x) { remove(1, si, x, 1); }void multiply(int l, int r, int s, int t, signed p, Matrix &v, short w){if (l >= s && r <= t){tr[p].v = tr[p].v * v, tr[p].ad += w;return;}down(p);if (mid >= s)multiply(l, mid, s, t, ls, v, w);if (mid < t)multiply(mid + 1, r, s, t, rs, v, w);update(p);}void multiply(int s, int t, Matrix &v, short w) { multiply(1, si, s, t, 1, v, w); }int ask_ans() { return tr[1].v.a[0][1]; }int rank(int l, int r, int s, int t, signed p){if (l >= s && r <= t)return tr[p].sum;down(p);int ans = 0;if (mid >= s)ans = rank(l, mid, s, t, ls);if (mid < t)ans += rank(mid + 1, r, s, t, rs);return ans;}int rank(int x) { return rank(1, si, 1, x, 1); }
} tr;
inline void insert(int i)
{if (++mp[id[i]] == 1){tr.insert(id[i], tr.rank(id[i]) + 1);tr.multiply(id[i] + 1, n, u[1], 1);}
}
inline void remove(int i)
{if (--mp[id[i]] == 0){tr.remove(id[i]);tr.multiply(id[i] + 1, n, ru[1], -1);}
}
signed main()
{// freopen("chk.in", "r", stdin);// freopen("chk.out", "w", stdout);n = read(), sq = sqrt(n);mod = read();for (int i = 1; i <= n; ++i)a[i] = read();copy(a + 1, a + n + 1, b + 1);sort(b + 1, b + n + 1);si = unique(b + 1, b + n + 1) - b;for (int i = 1; i <= n; ++i)id[i] = lower_bound(b + 1, b + si, a[i]) - b;for (int i = 1; i <= n; ++i)b[i] = b[i] % mod;fib[1] = fib[2] = 1;for (int i = 3; i <= n; ++i)fib[i] = Mod(fib[i - 1] + fib[i - 2]);u[1] = Matrix(1), ru[1] = Matrix(-1);for (int i = 2; i <= n; ++i)u[i] = u[i - 1] * u[1], ru[i] = ru[i - 1] * ru[1];m = read();for (int i = 1; i <= m; ++i)q[i].l = read(), q[i].r = read(), q[i].id = i;sort(q + 1, q + m + 1);int l = 1, r = 0;for (int i = 1; i <= m; ++i){while (l > q[i].l)insert(--l);while (r < q[i].r)insert(++r);while (l < q[i].l)remove(l++);while (r > q[i].r)remove(r--);res[q[i].id] = tr.ask_ans();}for (int i = 1; i <= m; ++i)write(res[i]), putchar('\n');return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/883473.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java笔记-15、Web后端基础 分层解耦

三层架构 满足单一职责原则。Controller控制层:接收前端发送的请求,对请求进行处理并响应数据。 Service业务逻辑层:处理具体的业务逻辑。 Dao数据访问层(持久层):负责数据访问操作,包括数据的增删改查。浏览器发过来请求,首先访问Controller层,Controller调用Service…

框架ThinkPHP

引子:本章主要介绍ThinkPHP(PHP开发框架)的简单使用和一些安全问题。免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!! 附:完整笔记目录~ ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正! 1.5 🐘框架&a…

我的“DeepSeek服务不忙了”,腾讯云671B满血模型无限量调用攻略!

DeepSeek R1虽然免费,但是基本到了无法使用的状态。一两轮对话后,就开始服务忙了。好在这是一个开源模型,大量的第三方平台开始上线了。上一篇我们就讲过硅基流动。最近听闻腾讯云也上线了 DeepSeek-V3、DeepSeek-R1 满血版模型。而且可以免费不限量使用。具体规则如下: 添…

ACM寒假集训第五次专题任务

ACM寒假集训第五次专题任务 一、自然数的拆分问题 题目:解题思路: 使用了深度优先搜索,通过he判断何时输出,c标记长度控制输出,qs标记起始位置从小到大拆分。 AC代码: #include<iostream> using namespace std; int n,a[10],ans; void dfs(int he,int c,int qs) {i…

DeepSeekR1+Cherry Studio使用白嫖API和开源软件使用满血版模型!

使用Ollama本地运行,使用Ollama+ChatWise可视化运行,使用Ollama+ChatWise在Macbook Air M1 上运行。今天再来说一个方案。这个方案不是完全离线,但是模型能力会比离线的强。可以完全免费尝试,有几百到几千万的Token可以用。可以缓解DeepSeek R1官方服务繁忙无法使用的问题。…

DeepSeekR1 苹果macbook M1本地可视化运行!

过年了,就带了一台 macbook air 8g,DeepSeekR1的消息还是铺天盖地的来,我就想着在这台电脑上也装一个吧。经过简单的配置,最终也运行起来了,速度还可以。我这是首款M系列笔记本,也是现在最低配的 M 系列笔记本。这也就意味着所有M系列的苹果电脑都可以轻松运行DeepSeekR1…

11.A星寻路算法

14.A星寻路算法 题目 迷宫寻路需求,在一个迷宫游戏中,有一些怪物攻击主角,现在希望小怪物,能自动绕过迷宫中的障碍物,寻找到主角的所在。 思路 A星寻路算法(A*search algorithm),是一种用于寻找有效路径的算法。 简单的场景举例(简化问题),看一看A星寻路算法的工作过程。…

人間になりたい。

さよならはエモーション 僕は行く ずっと涙こらえ こらえ 忘れてたエモーション 僕は行く ずっと深い霧の 霧の向こうへ『……组建过,那就好。』 属于我的 Crychic,就在那个寒假啊。 或许更早些,始于一次英语单元测同时爆炸了的三个人,经过一次精彩地赶在元旦零点钟声前分解…

【THM】Security Principles(安全原则)-学习

了解安全三元组以及常见的安全模型和原则。本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/securityprinciples 本文相关内容:了解安全三元组以及常见的安全模型和原则。介绍 网络安全已成为一个流行词;每家公司都声称其网络产品或网络服务是安全的,但事实上…

小米 R3G 路由器刷机教程(Pandavan)

小米 R3G 路由器以其高性价比和稳定的性能备受用户青睐。然而,原厂固件的功能相对有限,难以满足高级用户的个性化需求。刷机不仅可以解锁路由器的潜能,还能通过第三方固件实现更丰富的功能,如 DNS 解析、KMS 服务器、USB 管理等。本文旨在为小米 R3G 路由器用户提供详细的刷…

windows知道服务器的内网IP地址如何查看服务器的计算机名称

windows知道服务器的内网IP地址如何查看服务器的计算机名称windows知道服务器的内网IP地址如何查看服务器的计算机名称 nbtstat百度百科 https://baike.baidu.com/item/nbtstat/7578115 windows在局域网内查看ip地址对应的计算机名或者根据计算机名查ip https://blog.csdn.net/…