Codeforces 633H Fibonacci-ish II【线段树】
题目大意
给你一个序列a,Q次询问,每次询问\([l,r]\)
把\([l,r]\)的数排序去重,得到序列b,f是斐波那契数列
求\(\sum_{b=1}^{len} b_if_i\)
思路
发现单次如果加入和减去一个数
只需要把这个数的贡献加上/减去,然后把大于他的数斐波那契数的下标++/--
这个东西如果可以维护就可以完成单次加入个删除了
那么就可以用莫队来把询问离线处理
然后考虑加入一个数或者删除一个数
先离散化,用线段树维护起来
每个区间直接维护这个区间的答案
因为线段树需要累加标记,所以直接考虑把下表标加上k的贡献??
这东西需要一个结论\(f_{n+k}=f_{n}f_{k+1}+f_{n-1}{k}\)
发现\(\sum_{b=1}^{len} b_if_{i+k}=\sum_{b=1}^{len}b_i*f_if_{k+1}+\sum_{b=1}^{len}b_i*f_{i-1}f_{k}\)
发现只需要区间只需要维护两个值\(\sum_{b=1}^{len}b_if_i\)和\(\sum_{b=1}^{len}b_if_{i-1}\)就可以了
那么\(\sum_{b=1}^{len}b_if_{i-1}\),咋维护?
\(\sum_{b=1}^{len}b_if_{i-1}=\sum_{b=1}^{len}b_if_if_k+\sum_{b=1}^{len}f_{i-1}f_{k-1}\)
因为有减法操作,所以还需要处理斐波那契数列下标是负数的情况,加上偏移量逆推就行了
然后还需要一些卡常技巧
比如在单点加上贡献的时候,每次向左走就可以把右边区间的下标加上
然后可以线段树非递归卡卡常。。。。
能不取模就别取模
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
//convenient for
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-') w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 3e4 + 10;
int n, q, Mod;
int cnt[N] = {0}, pre[N], tot = 0, a[N];
int ans[N], f[N << 1];
struct Query {
int l, r, id;
} Q[N];
int block[N], siz_of_block;
bool cmp(Query a, Query b) {
if (block[a.l] == block[b.l]) return a.r < b.r;
return a.l < b.l;
}
int add(int a, int b) {
return (a += b) >= Mod ? a - Mod : a;
}
int sub(int a, int b) {
return (a -= b) < 0 ? a + Mod : a;
}
int mul(int a, int b) {
return 1ll * a * b % Mod;
}
void init() {
f[N] = 0, f[N + 1] = 1;
fu(i, N + 2, (N << 1) - 1) f[i] = add(f[i - 2], f[i - 1]);
fd(i, N - 1, 1) f[i] = sub(f[i + 2], f[i + 1]);
}
#define LD (t << 1)
#define RD (t << 1 | 1)
int val1[N << 2], val2[N << 2], tag[N << 2];
void pushup(int t) {
val1[t] = add(val1[LD], val1[RD]);
val2[t] = add(val2[LD], val2[RD]);
}
void pushnow(int t, int vl) {
int lastval1 = val1[t];
int lastval2 = val2[t];
tag[t] += vl;
val1[t] = (lastval1 * f[N + vl + 1] + lastval2 * f[N + vl]) % Mod;
val2[t] = (lastval1 * f[N + vl] + lastval2 * f[N + vl - 1]) % Mod;
}
void pushdown(int t) {
if (tag[t]) {
pushnow(LD, tag[t]);
pushnow(RD, tag[t]);
tag[t] = 0;
}
}
void insert(int t, int l, int r, int pos) {
while (l < r) {
pushdown(t);
int mid = (l + r) >> 1;
if (pos <= mid) {
pushnow(RD, 1);
t = LD, r = mid;
} else {
t = RD;
l = mid + 1;
}
}
val1[t] = mul(pre[l], f[N + tag[t] + 1]);
val2[t] = mul(pre[l], f[N + tag[t]]);
while (t >>= 1) pushup(t);
}
void remove(int t, int l, int r, int pos) {
while (l < r) {
pushdown(t);
int mid = (l + r) >> 1;
if (pos <= mid) {
pushnow(RD, -1);
t = LD, r = mid;
} else {
t = RD;
l = mid + 1;
}
}
val1[t] = val2[t] = 0;
while (t >>= 1) pushup(t);
}
void insert(int pos) {
if (++cnt[pos] == 1) insert(1, 1, tot, pos);
}
void remove(int pos) {
if (--cnt[pos] == 0) remove(1, 1, tot, pos);
}
int main() {
//freopen("input.txt", "r", stdin);
Read(n), Read(Mod);
init();
fu(i, 1, n) {
Read(a[i]);
pre[i] = a[i];
}
sort(pre + 1, pre + n + 1);
tot = unique(pre + 1, pre + n + 1) - pre - 1;
fu(i, 1, n) a[i] = lower_bound(pre + 1, pre + tot + 1, a[i]) - pre;
siz_of_block = sqrt(n);
fu(i, 1, n) block[i] = (i - 1) / siz_of_block + 1;
Read(q);
fu(i, 1, q) Read(Q[i].l), Read(Q[i].r), Q[i].id = i;
sort(Q + 1, Q + q + 1, cmp);
int l = 1, r = 0;
fu(i, 1, q) {
while (r < Q[i].r) insert(a[++r]);
while (r > Q[i].r) remove(a[r--]);
while (l > Q[i].l) insert(a[--l]);
while (l < Q[i].l) remove(a[l++]);
ans[Q[i].id] = val1[1];
}
fu(i, 1, q) {
Write(ans[i]);
putchar('\n');
}
return 0;
}
Codeforces 633H Fibonacci-ish II【线段树】的更多相关文章
- UVA10869 - Brownie Points II(线段树)
UVA10869 - Brownie Points II(线段树) 题目链接 题目大意:平面上有n个点,Stan和Ollie在玩游戏,游戏规则是:Stan先画一条竖直的线作为y轴,条件是必需要经过这个 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- Codeforces 446C —— DZY Loves Fibonacci Numbers(线段树)
题目:DZY Loves Fibonacci Numbers 题意比較简单,不解释了. 尽管官方的题解也是用线段树,但还利用了二次剩余. 可是我没有想到二次剩余,然后写了个感觉非常复杂度的线段树,还是 ...
- codeforces 22E XOR on Segment 线段树
题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...
- CDOJ 1259 昊昊爱运动 II 线段树+bitset
昊昊爱运动 II 昊昊喜欢运动 他N天内会参加M种运动(每种运动用一个[1,m]的整数表示) 现在有Q个操作,操作描述如下 昊昊把第l天到第r天的运动全部换成了x(x∈[1,m]) 问昊昊第l天到第r ...
- Codeforces 588E. A Simple Task (线段树+计数排序思想)
题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- SPOJ 1557. Can you answer these queries II 线段树
Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- Codeforces 444C DZY Loves Colors(线段树)
题目大意:Codeforces 444C DZY Loves Colors 题目大意:两种操作,1是改动区间上l到r上面德值为x,2是询问l到r区间总的改动值. 解题思路:线段树模板题. #inclu ...
随机推荐
- 8条规则图解JavaScript原型链继承原理
原形链是JS难点之一,而且很多书都喜欢用一大堆的文字解释给你听什么什么是原型链,就算有图配上讲解,有的图也是点到为止,很难让人不产生疑惑. 我们先来看一段程序,友情提示sublimeText看更爽: ...
- RabbitMQ入门(6)——远程过程调用(RPC)
在RabbitMQ入门(2)--工作队列中,我们学习了如何使用工作队列处理在多个工作者之间分配耗时任务.如果我们需要运行远程主机上的某个方法并等待结果怎么办呢?这种模式就是常说的远程过程调用(Remo ...
- u-boot-2015.07 make xxx_config 分析
1.u-boot编译脚本:mk.sh #! /bin/sh export PATH=$PATH:/opt/ti-sdk-am335x-evm-08.00.00.00/linux-devkit/sysr ...
- js中的内部属性与delete操作符
本文正式地址:http://www.xiabingbao.com/javascript/2015/08/03/javascript-delete-configurable 在讲解Configurabl ...
- 基于哈夫曼编码的压缩解压程序(C 语言)
这个程序是研一上学期的课程大作业.当时,跨专业的我只有一点 C 语言和数据结构基础,为此,我查阅了不少资料,再加上自己的思考和分析,实现后不断调试.测试和完善,耗时一周左右,在 2012/11/19 ...
- Request库使用response.text返回乱码问题
我们日常使用Request库获取response.text,这种调用方式返回的text通常会有乱码显示: import requests res = requests.get("https: ...
- bzoj1002: [FJOI2007]轮状病毒 生成树计数
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病毒的产生规 ...
- 1-27 sed基本编程和cut基本应用
大纲: 一.sed基本编程 sed详解.Usage.操作实例 二.cut命令应用 cut命令详解.Usage.操作实例 ######################################## ...
- 【MySQL】Error 1264: out of range value for column
此问题是插入的整型数字超出了范围. 比如设置表格的数据类型:cust_fax integer(10) not null 当插入以下数字的时候会抛出标题所说的错误: insert into databa ...
- Bootstrap 可视化布局--拖拽后弹窗进行编辑
Bootstrap 可视化布局--拖拽后弹窗进行编辑 最近后台想一个需求,使用可视化布局-中文 | en中拖拽表格后,弹窗进行编辑,保存下载后在后台生成pdf格式. 奈何各种问题不断,使用 jquer ...