Description

Transmission Gate

你需要维护一个长度为\(n \leq 300000\) 的数列,兹词两个操作:

1.给一个区间加上一个fibonacci数列,规定\(f[0] = 0, f[1] = 1, f[2] = 1\)

2.查询一段区间的和。对1e9+9取模

操作个数m不超过300000.

Solution

​ 这一题其实要考虑Fibonacci数列的两个性质:

​ (i)\(\sum_{i = 1}^{n} fib(i) = f(n + 2) - 1\)

​ (ii)令\(S_i = S_{i - 1} + S_{i - 2}\), 其中\(S_1 = a, S_2 = b\)

​ 那么\(S_i = aFib(i - 1) + bFib(i - 2)\)

​ 那么就很好做了, 在线段树中, 我们要只要记数列的前两项就可以方便的对数列进行求和,pushdown等操作.

​ 这题细节比较多,相关部分见代码。

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug(s) debug("The massage in line %d, Function %s: %s\n", __LINE__, __FUNCTION__, s)
typedef long long LL;
typedef long double LD;
const int BUF_SIZE = (int)1e6 + 10;
struct fastIO {
char buf[BUF_SIZE], buf1[BUF_SIZE];
int cur, cur1;
FILE *in, *out;
fastIO() {
cur = BUF_SIZE, in = stdin, out = stdout;
cur1 = 0;
}
inline char getchar() {
if(cur == BUF_SIZE) fread(buf, BUF_SIZE, 1, in), cur = 0;
return *(buf + (cur++));
}
inline void putchar(char ch) {
*(buf1 + (cur1++)) = ch;
if (cur1 == BUF_SIZE) fwrite(buf1, BUF_SIZE, 1, out), cur1 = 0;
}
inline int flush() {
if (cur1 > 0) fwrite(buf1, cur1, 1, out);
return cur1 = 0;
}
}IO;
#define getchar IO.getchar
#define putchar IO.putchar
int read() {
char ch = getchar();
int x = 0, flag = 1;
for(;!isdigit(ch); ch = getchar()) if(ch == '-') flag *= -1;
for(;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
return x * flag;
}
void write(int x) {
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar(x % 10 + 48);
}
void putString(char s[], char EndChar = '\n') {
rep(i, 0, strlen(s) - 1) putchar(*(s + i));
if(~EndChar) putchar(EndChar);
} #define Maxn 300009
const LL Mod = 1000000009;
int n, a[Maxn], m; LL f[Maxn];
struct node { LL x, y; };
LL FibDelta(LL F1, LL F2, LL len) {
LL res = 0;
if(len >= 1) (res += F1) %= Mod;
if(len >= 2) (res += F2) %= Mod;
if(len >= 3) (res += (F2 * (f[len + 1] - 2ll) % Mod + F1 * (f[len] - 1ll) % Mod) % Mod) %= Mod;
return res;
}// It needs to analysis in different conditions
node FibForward(node s, int len) {
LL c = s.x * f[len] % Mod + s.y * f[len + 1] % Mod, d = s.x * f[len + 1] % Mod + s.y * f[len + 2] % Mod;
return (node){c % Mod, d % Mod};
}
namespace SGMT_tree {
LL tree[Maxn << 2], beg[Maxn << 2][2], val[Maxn << 2];
#define lc(x) (x) << 1
#define rc(x) (x) << 1 | 1
#define ls rt << 1, l, mid
#define rs rt << 1 | 1, mid + 1, r
void pushup(int rt) { tree[rt] = (1ll * tree[lc(rt)] + 1ll * tree[rc(rt)]) % Mod; }
void pushdown(int rt, int l, int r) {
int mid = (l + r) >> 1;
if(val[rt]) {
LL &a = beg[rt][0], &b = beg[rt][1];
(beg[lc(rt)][0] += a) %= Mod, (beg[lc(rt)][1] += b) %= Mod;
(tree[lc(rt)] += FibDelta(a, b, mid - l + 1)) %= Mod;
val[lc(rt)] = 1; LL c = a * f[mid - l] + b * f[mid - l + 1], d = a * f[mid - l + 1] + b * f[mid - l + 2];
c %= Mod, d %= Mod;
(beg[rc(rt)][0] += c) %= Mod, (beg[rc(rt)][1] += d) %= Mod;
(tree[rc(rt)] += FibDelta(c, d, r - mid)) %= Mod;
val[rc(rt)] = 1;
beg[rt][0] = beg[rt][1] = 0;
val[rt] = 0;
}
}
void build(int rt, int l, int r) {
if(l == r) {
tree[rt] = a[l];
return ;
}
int mid = (l + r) >> 1;
build(ls), build(rs);
pushup(rt);
}
void modify(int rt, int l, int r, int x, int y, int p1, int p2) {
if(x <= l && r <= y) {
(beg[rt][0] += p1) %= Mod, (beg[rt][1] += p2) %= Mod;
(tree[rt] += FibDelta(p1, p2, r - l + 1)) %= Mod;
val[rt] = 1;
return ;
} int mid = (l + r) >> 1;
pushdown(rt, l, r); if(y <= mid) modify(ls, x, y, p1, p2);
else if(mid + 1 <= x) modify(rs, x, y, p1, p2);
else {
modify(ls, x, mid, p1, p2); /**/
node z = FibForward((node){p1, p2}, mid - x);/**/
//F[i] -> F[i + mid - x]: p1 -> z.x, p2 -> z.y
modify(rs, mid + 1, y, z.x, z.y);/*The InterVal needs to move*/
}
pushup(rt);
}
int query(int rt, int l, int r, int x, int y) {
if(x <= l && r <= y) return tree[rt]; int mid = (l + r) >> 1; pushdown(rt, l, r); if(y <= mid) return query(ls, x, y);
else if(mid + 1 <= x) return query(rs, x, y);
else return (1ll * query(ls, x, y) + 1ll * query(rs, x, y)) % Mod;
}
#undef lc
#undef rc
#undef ls
#undef rs
}
namespace INIT {
void Main() {
n = read(), m = read(); f[1] = 1; f[2] = 1;
rep(i, 3, n + 4) f[i] = (f[i - 1] * 1ll + f[i - 2]) % Mod; rep(i, 1, n) a[i] = read(); SGMT_tree :: build(1, 1, n);
}
}
namespace SOLVE {
void Main() {
rep(i, 1, m) {
int opt = read(); if(opt == 1) {
int x = read(), y = read();
SGMT_tree :: modify(1, 1, n, x, y, 1, 1);
}
if(opt == 2) {
int x = read(), y = read();
write(SGMT_tree :: query(1, 1, n, x, y)), putchar('\n');
}
}
}
}
int main() {
freopen("CF446C.in", "r", stdin);
freopen("CF446C.out", "w", stdout); INIT :: Main();
SOLVE :: Main();
#ifdef Qrsikno
debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif
return IO.flush();
}

CF446C [DZY loves Fibonacci]的更多相关文章

  1. cf446C DZY Loves Fibonacci Numbers

    C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...

  2. 【思维题 线段树】cf446C. DZY Loves Fibonacci Numbers

    我这种maintain写法好zz.考试时获得了40pts的RE好成绩 In mathematical terms, the sequence Fn of Fibonacci numbers is de ...

  3. CF446C DZY Loves Fibonacci Numbers 线段树 + 数学

    有两个性质需要知道: $1.$ 对于任意的 $f[i]=f[i-1]+f[i-2]$ 的数列,都有 $f[i]=fib[i-2]\times f[1]+fib[i-1]\times f[2]$ 其中 ...

  4. 「CF446C」 DZY Loves Fibonacci Numbers

    「CF446C」 DZY Loves Fibonacci Numbers 这里提供一种优美的根号分治做法. 首先,我们考虑一种不太一样的暴力.对于一个区间加斐波那契数的操作 \([a,b]\),以及一 ...

  5. codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)(两种方法)

    In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 ...

  6. Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列

    C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...

  7. Codeforces Round #FF 446 C. DZY Loves Fibonacci Numbers

    參考:http://www.cnblogs.com/chanme/p/3843859.html 然后我看到在别人的AC的方法里还有这么一种神方法,他预先设定了一个阈值K,当当前的更新操作数j<K ...

  8. Codeforces446C - DZY Loves Fibonacci Numbers

    Portal Description 给出一个\(n(n\leq3\times10^5)\)个数的序列,进行\(m(m\leq3\times10^5)\)次操作,操作有两种: 给区间\([L,R]\) ...

  9. [CodeForces - 447E] E - DZY Loves Fibonacci Numbers

    E  DZY Loves Fibonacci Numbers In mathematical terms, the sequence Fn of Fibonacci numbers is define ...

随机推荐

  1. Java中设置Session过期时间(Spring Boot)

    1.Spring Boot: server.session.cookie.comment = #注释会话cookie. server.session.cookie.domain = #会话cookie ...

  2. 国内代码托管平台(Git和SVN)

        Github(Git和SVN)https://github.com/ 可以说GitHub的出现完全颠覆了以往大家对代码托管网站的认识.GitHub不但是一个代码托管网站,更是一个程序员的SNS ...

  3. 【转】C++函数的重载、覆盖和隐藏区别

    网上看到的关于C++函数的重载.覆盖和隐藏区别的回答,如下(其内容来源于C++面试宝典中一道题目): a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:( ...

  4. 弄技术要弄通-公司reis的pub/sub怎么使用的呢?

    Pub/Sub in Redis using PHP Posted on November 14, 2011by xmeng I would like to put an example togeth ...

  5. 再说javascript 的__proto__ 和prototype 属性

    过了一段时间,没写 原生的 javascript 的了,感觉天天在用框架写代码,框架写代码完全限定死了你所需要思考的东西,只是在处理一些业务逻辑,真正的代码 都感觉不会写了. 突然发现,框架用的不熟悉 ...

  6. 一个IM开源项目LiteTalk

    http://blog.csdn.net/visualwind/article/details/6086631 http://blog.sina.com.cn/s/blog_54b5ea250101n ...

  7. openstack kolla多节点容器化环境安装

    好久没写随笔了,6月份趁着在公司没有太忙的事儿,把公司的服务器进行了虚拟化,采用的openstack当前的容器化方案kolla. 整体安装完的感受时,小白感觉自己是个大牛!哈哈,开玩笑,由于以前是开发 ...

  8. What to do about Eclipse's “No repository found containing: …” error messages?

    As Mauro said: "you have to remove and re-add the Eclipse Project Update site, so that its meta ...

  9. 嵌入式开发之davinci--- mcfw框架介绍

    整体上mcfw框架如下图 从中可见其层次是清楚的,link实在基本的驱动之上的,而mcfw是在link之上的api,是通过link来实现相应的功能.可见link是框架中承上启下的层次,通过link来实 ...

  10. xcode6-添加真机设备

    xcode6-添加真机设备 第一:添加真机设备 1:到苹果开发者中心,中得iOS-APPs,在列表中得Devices中,选择All-点击右侧的"+",添加真机设备. 会打开下面的页 ...