线段树

【数据结构】——线段树板子

元气小坏坏 提交于 2019-12-03 14:24:38
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int read(){ 5 int x=0,f=1; 6 char c=getchar(); 7 while(!isdigit(c)){ 8 if(c=='-') f=-1; 9 c=getchar(); 10 } 11 while(isdigit(c)){ 12 x=(x<<1)+(x<<3)+(c^48); 13 c=getchar(); 14 } 15 return x*f; 16 } 17 const int N=1e5+10; 18 int n,m,p; 19 int a[N]; 20 struct tree{ 21 ll sum[N<<2]; 22 ll add[N<<2],mul[N<<2]; 23 int ls(int o){return o<<1;} 24 int rs(int o){return o<<1|1;} 25 void pushup(int o){ 26 sum[o]=(sum[ls(o)]+sum[rs(o)])%p; 27 } 28 void pushdown(int o,int l,int r){ 29 int mid=(l+r)>>1; 30 sum[ls(o)]=(sum[ls(o)]*mul

luogu_ P3372 【模板】线段树 1

半腔热情 提交于 2019-12-03 13:37:05
分块板题 #include<iostream> #include<cstdio> #define ri register int #define u long long namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using opt::in; #define NN 100005 namespace fun_ki{ struct node{ u l,r,sum,add; }a[NN]; u pos[NN],poi[NN]; void update(const u &l,const u &r,const u &x){ u p(pos[l]),q(pos[r]); if(p^q){ for(ri i(p+1);i<=q-1;++i) a[i].add+=x; for(ri i(l);i<=a[p].r;++i) poi[i]+=x; for(ri i(a[q].l);i<=r;++i) poi[i]+=x; a[p].sum+=(a[p].r-l

Codeforces 750E 线段树DP

可紊 提交于 2019-12-03 13:30:25
题意:给你一个字符串,有两种操作:1:把某个位置的字符改变。2:询问l到r的子串最少需要删除多少个字符,使得这个子串含有2017子序列,并且没有2016子序列? 思路:线段树上DP,我们设状态0, 1, 2, 3, 4分别为: null, 2, 20, 201, 2017的最小花费,我们用线段树来维互状态转移的花费矩阵,合并相邻的两个子串的时候直接转移即可。 代码: #include <bits/stdc++.h> #define INF 0x3f3f3f3f #define ls (o << 1) #define rs (o << 1 | 1) using namespace std; const int maxn = 200010; int a[maxn]; char s[maxn]; struct node { int f[5][5]; void init(int x) { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if(i == j) continue; f[i][j] = INF; } } if(x == 2) { f[0][0] = 1, f[0][1] = 0; } else if (x == 0) { f[1][1] = 1, f[1][2] = 0; } else if (x == 1)

Codeforces Round 718C (矩阵线段树)

笑着哭i 提交于 2019-12-03 13:27:57
Sasha has an array of integers a 1 ,  a 2 , ...,  a n . You have to perform m queries. There might be queries of two types: 1 l r x — increase all integers on the segment from l to r by values x ; 2 l r — find , where f ( x ) is the x -th Fibonacci number. As this number may be large, you only have to find it modulo 10 9  + 7 . In this problem we define Fibonacci numbers as follows: f (1) = 1 , f (2) = 1 , f ( x ) =  f ( x  - 1) +  f ( x  - 2) for all x  > 2 . Sasha is a very talented boy and he managed to perform all queries in five seconds. Will you be able to write the program that performs

Codeforces719E 矩阵乘法+线段树

二次信任 提交于 2019-12-03 13:23:10
Codeforces 719E 矩阵乘法+线段树 题目大意: 给定一个数列,请完成下面的两种操作 1.1 1 r z [ l , r ] //--> 区间加上一个数 z //--> 2.2 l r 查询 [ l , r ] //--> 区间内所有的数字,对应在 f i b //--> 中的值 例如 序列 1 3 2 4 5 ,2 2 3的结果就是 f i b ( 2 ) + f i b ( 2 ) + f i b ( 3 ) = 4 //--> 区间的加法我们很容易想到线段树,但是这时求得已经不是原区间的和了,而是在 f i b //--> 数列中对应项的和,我们考虑转化 首先,正常求 f i b //--> 数列的第 k //--> 项,我们可以利用矩阵乘法快速求出,大概是 ( f i b ( i − 2 ) f i b ( i − 1 ) ) ∗ ( 1 1 1 0 ) = ( f i b ( i − 1 ) f i b ( i ) ) //--> 由于矩阵乘法具有结合律,将中间的矩阵快速幂再乘上第一个矩阵可以得到最后想要的 f i b ( i ) //--> ,在这道题目中,我们其实还用到了另外一个性质:矩阵乘法在合法的情况下具有分配率,即 E ∗ ( A + B ) = E ∗ A + E ∗ B //--> 且 ( A + B ) ∗ E = A ∗ E + B ∗ E

线段树+矩阵快速幂 codeforces718C Sasha and Array

放肆的年华 提交于 2019-12-03 13:22:54
传送门: 点击打开链接 题意:操作1,区间[l,r]的数字+x 操作2,求sigma f(i),l<=i<=r,f是斐波那契数列。 答案取模1e9+7 首先斐波那契数列用矩阵快速幂求,谁都会的。 这里有一个矩阵乘法的性质,A*B+A*C=A*(B+C) 有了这个性质,这题就非常傻逼了。 在求斐波那契数列中,是A*F,A是变换矩阵,F是列矩阵 那么我们用线段树的懒惰标记维护A矩阵,然后用sum维护F矩阵 之后在线段树上,就变成了区间更新乘以x。 就是一个很简单的手速题了。 #include <map> #include <set> #include <cmath> #include <ctime> #include <stack> #include <queue> #include <cstdio> #include <cctype> #include <bitset> #include <string> #include <vector> #include <cstring> #include <iostream> #include <algorithm> #include <functional> #define fuck(x) cout<<"["<<x<<"]"; #define FIN freopen("input.txt","r",stdin); #define FOUT

codeforces 1252K 线段树维护矩阵

喜夏-厌秋 提交于 2019-12-03 13:22:37
分析 对于操作一,相当于翻转,我们可以用异或去处理这个标记 对于操作二,即查询 [ L , R ] [L,R] [ L , R ] 这个区间的结果 对于初始值 a , b {a,b} a , b ,我们有 x 1 ∗ a + y 1 ∗ b , x 2 ∗ a + y 2 ∗ b {x1 * a + y1 * b, x2 * a + y2 * b} x 1 ∗ a + y 1 ∗ b , x 2 ∗ a + y 2 ∗ b ,即 A , B {A,B} A , B 其实这个操作就是一个矩阵的变化 我们维护一个 2 × 2 2×2 2 × 2 的矩阵 { a b } ∗ { 1 0 1 1 } = { a + b b } \left\{ \begin{matrix} a & b \end{matrix} \right\} * \left\{ \begin{matrix} 1 & 0 \\ 1 & 1 \end{matrix} \right\}= \left\{ \begin{matrix} a+b & b \end{matrix} \right\} { a ​ b ​ } ∗ { 1 1 ​ 0 1 ​ } = { a + b ​ b ​ } { a b } ∗ { 1 1 0 1 } = { a a + b } \left\{ \begin{matrix} a & b \end

Codeforces 718C 线段树+矩乘

泪湿孤枕 提交于 2019-12-03 13:22:23
题意: 维护一个序列,支持两种操作: 1.区间[l,r]的权值+x 2.询问区间[l,r]的函数和,即∑fib(x)这里的函数即斐波那契函数 数据范围:1≤n,q≤10 5 思路: 一般求斐波那契函数的方法可以考虑矩阵乘法,这里也是这样的。 我们不用线段树维护权值,我们用线段树维护线段树维护区间矩阵和。 有一个矩阵乘法的性质:A*B+A*C=A*(B+C) 在求斐波那契数列中,是A*F,A是变换矩阵,F是列矩阵 那么我们用线段树的lazy标记维护A矩阵,然后用sum维护F矩阵 之后在线段树上,就变成了区间更新乘以x。 // By SiriusRen #include <bits/stdc++.h> using namespace std; const int mod= 1000000007 ,N= 100050 ; int n,m,op,xx,yy,zz; struct Matrix{ int a[ 2 ][ 2 ]; void init(){memset(a, 0 , sizeof (a));} void dia(){a[ 0 ][ 0 ]=a[ 1 ][ 1 ]= 1 ,a[ 0 ][ 1 ]=a[ 1 ][ 0 ]= 0 ;} }sum[N << 3 ],lazy[N<< 3 ], base ; Matrix operator * (Matrix a,Matrix b){

codeforces 914D(线段树)

懵懂的女人 提交于 2019-12-03 13:21:08
题意: 1单点更新 2查询[l,r]区间的值最多改变一个能不能使得区间的gcd等于给出的x,但是此改变不改变原来的值。 思路:线段树维护gcd,很简单。查询的时候可以维护一个cnt的值,表示为当一个点的值不整除x的时候,对数进行改变的个数。当cnt>1的时候,直接结束函数。 #include<bits/stdc++.h> using namespace std; const int maxn = 5e5 + 10; typedef long long ll; #define clr(x,y) memset(x,y,sizeof x) #define INF 0x3f3f3f3f typedef pair<int,int> P; const ll Mod = 1e9 + 7; int gcd(int x,int y) { return y ? gcd(y,x % y) : x; } int a[maxn]; int tree[maxn << 2]; void build(int l,int r,int rt) { if(l == r) { tree[rt] = a[l];return ; } int mid = (l + r) >> 1; build(l,mid,rt << 1);build(mid + 1,r,rt << 1|1); tree[rt] = gcd(tree[rt <

CSPS模拟 100

我的未来我决定 提交于 2019-12-03 11:38:29
    我又挂分了T_T     这么吉利的数字..本来想考的好一点的     T1       没加当前弧优化(其实也不会),若志了       各种低错连篇而且 没想到点不联通..没有奇度点就直接从1开始搜了       于是喜提70(犯了这两个若志错误应该爆零的好吗)     T2       找规律。       设$f(i)$为点i右边比它小的数的个数       一次排序后,$j_k$左侧的点的f值不变       $j_k$右边比它大的点的f也不变       也就是排了谁,谁的f清零       线段树找谁被会被排序     T3       状压&树上背包       初始值赋成0就会过不去大样例。       考试的时候调了好久好久好久好久       结果考完了,改成-INF       A了555555  (╥_╥) 来源: https://www.cnblogs.com/yxsplayxs/p/11794277.html