COGS 2638. 数列操作ψ 线段树】的更多相关文章

传送门 : COGS 2638. 数列操作ψ 线段树 这道题让我们维护区间最大值,以及维护区间and,or一个数 我们考虑用线段树进行维护,这时候我们就要用到吉司机线段树啦 QAQ 由于发现若干次and,or之后,如果数据分布均匀,那么几乎所有的数在若干次操作后都会变成同一个数 因为我们的and操作中的0位,以及or操作当中的1位,都是可以把整个区间的那一二进制位重置为相同的 我们考虑利用这一个性质 如果我们直接维护一个区间内的值是否是相同的,那么效果会差很多. 我们发现我们在进行and操作的时…
题目链接: http://cogs.pro/cogs/problem/problem.php?pid=2638 Solution 用jry推荐的写法即可做到单次$O(log^{2}N)$,不过随机数据下表现非常优秀. $log^{2}$大概就是一共$log$位,然后每位$O(N)$级的,所以一共$NlogN$段,每段在线段树上又是$log$. jls给的详细证明就是说,每位单独考虑形成一个01串,势能函数就是每位差分后的$1$的个数,太详细的啥我也不是很熟练了..要是有路过的大神能详细讲一下咩Q…
BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知 道N次操作后数列中所有元素的和.他还要玩其他游戏,所以这个问题留给你解决. Input 第一行一个整数N,然后有N行,每行三个正整数a.b.k. N<=40000 , a.b.k<=10^9 Output 一个数,数列中所有元素的和 Sampl…
[题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对19940417取膜. 咋做 我们这一类题看来有一个套路就是用线段树维护一个DP数组,然后线段树节点合并就用一点组合的技巧.. 设\(dp(i)\)表示在该区间里选择\(i\)个乘起来的和,考虑如何合并区间,很简单就是 \[ dp(i)=\sum_{j=0}dp'(j)dp''(i-j) \] 先考虑…
http://cogs.pro:8080/cogs/problem/problem.php?pid=pyNimmVeq 264. 数列操作 ★☆   输入文件:shulie.in   输出文件:shulie.out   简单对比时间限制:1 s   内存限制:160 MB [问题描述] 给定一个数列 A,请实现如下两种操作: 1. 将 Ak 的值加 d. 2. 查询 As+As+1+⋯+At(s≤t) 的值. [输入格式] 第一行为一个整数 n(0≤n≤100000),表示数列 A 的大小. 第…
题目传送门 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]},支持两种操作: 1.1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上.即:令a[L]=a[L]+K,a[L+1]=a[L+1]+K+D, a[L+2]=a[L+2]+K+2D……a[R]=a[R]+K+(R-L)D. 2.2…
原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知道N次操作后数列中所有元素的和.他还要玩其他游戏,所以这个问题留给你解决. 输入 第一行一个整数N,然后有N行,每行三个正整数a.b.k. N<=40000 , a.b.k<=10^9 输出 一个数,数列…
蒟蒻的数列 bzoj-4636 题目大意:给定一个序列,初始均为0.n次操作:每次讲一段区间中小于k的数都变成k.操作的最后询问全局和. 注释:$1\le n\le 4\cdot 10^4$. 想法:那个操作就是一个不好好说话的操作,说白了就是对区间的每一个数取max 然后我们对于那个序列建立分治线段树.每个操作我都把它挂在对应的log的点上. n个操作都执行完了之后我们从1号节点深搜,更新答案即可. 最后,附上丑陋的代码... ... #include <iostream> #include…
1317. 数列操作C ★★★   输入文件:shuliec.in   输出文件:shuliec.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 假设有一个长度为 n(n≤100000) 的数列 A,支持如下两种操作: 1. 将 Ai,Ai+1,…,Aj 的值均增加 d 2. 查询 As+As+1+⋯+At(s≤t) 的值. 根据操作要求进行正确操作并输出结果. [输入格式] 第一行为一个正整数 n,表示数列的大小. 第二行有 n 个整数,表示数列 A 各项的初始…
1316. 数列操作B ★★   输入文件:shulieb.in   输出文件:shulieb.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 假设有一个大小为 n(n≤100000) 整数数列 A,支持如下两种操作: 1. 将 Ai,Ai+1,…,Aj 的值均增加 d 2. 查询 Ai 的值 根据操作要求进行正确操作并输出结果. [输入格式] 输入文件第一行一个整数 n, 第二行为 n 个整数,表示数列 A 中各项的初始值. 第三行为一个整数 m ,表示操作数.…
2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 678  Solved: 246[Submit][Status][Discuss] Description 有一个长度为n的序列,有三个操作1.I a b c表示将[a,b]这一段区间的元素集体增加c,2.R a b表示将[a,b]区间内所有元素变成相反数,3.Q a b c表示询问[a,b]这一段区间中选择c个数相乘的所有方案的和mod 19940417的值. Input 第一…
1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1961  Solved: 991[Submit][Status][Discuss] Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区…
首先想到线段树,然后刚开始写忽然想到树状数组求和岂不是更快,而且编程复杂度又小,于是把之前写的删掉,写树状数组,写完模版之后忽然发现这题竟然是区间修改! 于是又删掉重写,忽然发现不会处理又加又乘的,果断看题解…… 经过几乎两个小时的调试,终于1A. 需要注意的是,一定要让线段树的每一个区间保存的值时刻为正确的,这样才能在调用时直接返回.比如说这道题的change和query操作的最后一句话: sum:=f(g[k<<1]+g[k<<1+1]) 而不是 sum:=f(t[k<&…
略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream>   #define rep( i , n ) for( int i = 0 ; i < n ; i++ ) #defin…
题目 P1438 无聊的数列 解析: 先考虑修改,用差分的基本思想,左端点加上首项\(k\),修改区间\((l,r]\)内每个数的差分数组都加上公差\(d\),最后的\(r+1\)再减去\(k+(r-l)\times d\). 查询的话就是求出\(1-p\)的前缀和,也就是区间求和. 不难看出,这实际上就是一个点修改+区间修改+区间求和的题,所以直接上线段树,用线段树维护差分数组. 这个题目还有坑点就是要判断\(l,r\)的大小关系和\(r+1\)是否出界. 代码 #include <bits/…
传送门 线段树好题. 维护区间加,区间取最大值,维护区间最小值,历史区间最小值. 同样先考虑不用维护历史区间最小值的情况,这个可以参考这道题的解法,维护区间最小和次小值可以解决前两个操作,然后使用历史标记的常规维护方式合并标记更新就行了. 代码: #include<bits/stdc++.h> #define lc (p<<1) #define rc (p<<1|1) #define mid (T[p].l+T[p].r>>1) #define N 5000…
题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3 a b 询问[a, b]区间内总共有多少个1 4 a b 询问[a, b]区间内最多有多少个连续的1 对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,…
[BZOJ2962]序列操作 Description 有一个长度为n的序列,有三个操作1.I a b c表示将[a,b]这一段区间的元素集体增加c,2.R a b表示将[a,b]区间内所有元素变成相反数,3.Q a b c表示询问[a,b]这一段区间中选择c个数相乘的所有方案的和mod 19940417的值. Input 第一行两个数n,q表示序列长度和操作个数. 第二行n个非负整数,表示序列. 接下来q行每行输入一个操作I a b c或者 R a b或者Q a b c意义如题目描述. Outp…
咕咕了...于是借鉴了小粉兔的做法ORZ... 其实就是维护最大子段和的线段树,但上面又多了一些操作....QWQ 维护8个信息:1/0的个数(sum),左/右边起1/0的最长长度(ls,rs),整段区间中1/0的连续最长长度(mx). 于是对于各个操作,我们有了一些tag... tg1[]是区间赋值标记,没有标记时为-1,有标记时为0或1:tg2[]是区间取反标记,没有标记时为 0,有标记时为1. 注意标记下传时要先传tg1[],再传tg2[],否则取反标记会被赋值标记覆盖 #include<…
时间限制:1 s   内存限制:160 MB [问题描述] 假设有一列数 {Ai }(1 ≤ i ≤ n) ,支持如下两种操作: (1)将 A k 的值加 D .( k, D 是输入的数) (2) 输出 A s +A s+1 +…+A t .( s, t 都是输入的数, S ≤ T ) 根据操作要求进行正确操作并输出结果. [输入格式] 输入文件第一行一个整数 n(0<=n<=100000) , 第二行为 n 个整数,表示 {A i } 的初始值. 第三行为一个整数 m(0<=m<…
题意 直接照搬原题面 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 分析 先树剖一下,按重新编号的点建线段树 操作1:直接单点修改 操作2:一个子树里的点的编号是连在一起的,直接区间修改 操作3:该点的\(top\)不为1时,即该点跟根结点不在一条链上,加上这条链的贡献(线段树的区…
传送门 解题思路 区间加等差数列+单点询问,用差分+线段树解决,线段树里维护的就是差分数组,区间加等差数列相当于在差分序列中l位置处+首项的值,r+1位置处-末项的值,中间加公差的值,然后单点询问就相当于在差分数列中求前缀和. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; ; typedef long long LL;…
正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$easy$?维护下区间内01个数然后翻转就打$tag$,除了有点儿麻烦还是挺$easy$的鸭$QwQ$,顺便强调下顺序?就如果区间覆盖就可以直接把翻转删了,区间翻转的时候不用管覆盖,每次下放先覆盖后翻转,$over$ 说下操作五$QwQ$,就再维护几个东西$QwQ$ 就,维护下区间内最长的连续的1的个数,…
LINK:WD与数列 这道题可谓妙绝 我明白了一个增量统计的原理. 原本的想法是:差分之后 显然长度为1的单独统计 长度为2的以及更多就是字符串之间的匹配问题了. 对差分序列建立SAM 由于第一个是一定匹配的 且后面的大小关系相同 所以可以直接取差分后的来建立SAM. 考虑计算答案 容易想到对于某个节点单独统计答案 那就是right集合上len暴力扫了 可能可以通过45分 我没试过 且这个暴力过于暴力 也不好说明复杂度. 考虑一件事情 其实统计答案的本质是 len.right集合中x,y三者之间…
变了个花样,在l~r区间加上一个等差数列,等差数列的显著特点就是公差d,我们容易想到用线段树维护差分数组,在l位置加上k,在l+1~r位置加上d,最后在r+1位置减去k+(l-r)*d,这样就是在差分数组上操作,利用线段树打标记容易实现. 最后对于每个查询的位置t,查询1~t的区间和就是t位置上的数值. #include<bits/stdc++.h> using namespace std; const int N=1e5+10; #define ll long long int data[N…
自己搞的算法超时了..但是思路没什么问题:用线段树维护每个点到叶子节点的距离即可 /* 线段树维护区间最小值,每次向下访问,就把访问到的点对应的区间段减去边权 到另一颗子树访问时,向上回溯时加上减去的边权即可; */ #include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 500050 #define INF 0x3f3f3f3f3f3f3f3f struct Query{ int x,l,r…
什么是线段树合并? 首先你需要动态开点的线段树.(对每个节点维护左儿子.右儿子.存储的数据,然后要修改某儿子所在的区间中的数据的时候再创建该节点.) 考虑这样一个问题: 你现在有两棵权值线段树(大概是用来维护一个有很多数的可重集合那种线段树,若某节点对应区间是\([l, r]\),则它存储的数据是集合中\(\ge l\).\(\le r\)的数的个数),现在你想把它们俩合并,得到一棵新的线段树.你要怎么做呢? 提供这样一种算法(tree(x, y, z)表示一个左儿子是x.右儿子是y.数据是z的…
题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案数就是答案了 最长上升子序列随便求求,主要是这个方案数很麻烦啊--我的做法是对每一个长度开一个动态开点线段树,然后每次在对应的长度里二分跑前缀和 其实这里完全不用动态开点线段树的,直接把权值离散一下然后一棵线段树就够了,跑得飞快 其实这里连线段树都不需要直接树状数组就可以维护前缀最大值和方案之和了…
---题面--- 题解: 在考场上打的这道题,出人意料的很快就打完了?! 直接用线段树,维护几个东西: 1,lazy标记 : 表示区间赋值 2,mark标记:表示区间翻转 3,l1:前缀最长连续的1的子段长度 4,l0:前缀最长连续的0的子段长度 5,m0:区间内最长的全为0的子段的长度 6,r0:后缀最长连续的0的子段长度 7,r1:后缀最长连续的1的子段长度 8,m1:区间内最长的全为1的子段的长度 9,sum :区间和 维护起来比较繁琐,细节较多,但是都不难,是可以自己想出来的. 这里提一…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1858 线段树...调了一个上午...(后面带 // 的都是改出来的) lazy 标记的下放好麻烦,还得考虑赋值和取反的先后顺序什么的... 因为在取反时把赋值标记 swap 了,所以下放的时候先判断取反再判断赋值... 而且WA了一上午的原因竟然是一开始不慎把取反以为成翻转了,后来没改干净...那个 rev 的名字啊... 总之没有太改变自己最初的想法.改了些细节就A了还是很高兴的! 代码…