| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 游戏开发 -> 前缀和及其变形 -> 正文阅读 |
|
[游戏开发]前缀和及其变形 |
前缀和及其变形前缀和对于一般的前缀和来说,是方便求一个区间内任意区间和的一个操作, 对于 取模的前缀积前置知识费马小定理 1.对于给定的一个素数P 2.存在p个余数类: 0 , 1 , 2 , 3 , . . . . . . , p ? 1 {0 , 1 , 2 , 3 , ...... , p-1} 0,1,2,3,......,p?1 3.同余, 表示两个数mod同一个数后值相等 7 % 4 = 3 , ? 11 % 4 = 3 7 \%4=3,\ 11\%4=3 7%4=3,?11%4=3,就称7和11是对4同余的 4.性质: 如果存在 a = b ( m o d ? p ) a=b(mod\ p) a=b(mod?p)以及 c = d ( m o d ? p ) c=d(mod\ p) c=d(mod?p)此时的等于表示同余关系 那么就有 ( a ? b ) / p = z ( z 为 整 数 ) (a-b)/p=z(z为整数) (a?b)/p=z(z为整数)同理可以推出 ( c ? d ) / p = z ( z 为 整 数 ) (c-d)/p=z(z为整数) (c?d)/p=z(z为整数) 就有 ( ( a + c ) ? ( b + d ) ) / p = z ( z 为 整 数 ) ((a+c)-(b+d))/p=z(z为整数) ((a+c)?(b+d))/p=z(z为整数),就可以推出 a + c = b + d ( m o d ? p ) a+c=b+d(mod\ p) a+c=b+d(mod?p) 同理,我们还有 a ? c = b ? d ( m o d ? p ) , ? a ? c = b ? d ( m o d ? p ) , ? 并 且 ? a n = b n ( m o d ? p ) a-c=b-d(mod\ p),\ a*c=b*d(mod\ p),\ 并且\ a^n=b^n(mod\ p) a?c=b?d(mod?p),?a?c=b?d(mod?p),?并且?an=bn(mod?p) (加法,减法和乘法对于取模都是封闭的) 5.同余的逆: 对于一个非零的数a,如果这个数不能被p整除,即 a ? m o d ? p ≠ 0 a\ mod\ p \ne 0 a?mod?p?=0 那么一定存在一组数b使得 a ? b ? m o d ? p = 1 a*b\ mod\ p=1 a?b?mod?p=1 在同余的条件下,我们称b为a的逆
对于所有互素的a和p都存在 a p ? 1 = 1 ( m o d ? p ) a^{p-1}=1(mod\ p) ap?1=1(mod?p) 那么对于一个数a,与p互质,则存在一个b使得 a ? b = 1 ( m o d ? p ) a*b=1(mod\ p) a?b=1(mod?p),由Fermat小定理可得, b = a p ? 2 b=a^{p-2} b=ap?2 所以,若a和p互质,就有a的逆为 a p ? 2 a^{p-2} ap?2. 前缀积和前缀和类似,前缀积也可以用除法来实现O(1)查询某一段的积的作用 这个时候我们就要用Fermat小定理中的内容将除法转化为求逆元的操作,对于余数群来讲,是等价的, 由此我们可以用 对于某一个数的前缀积来讲,就有 广义的前缀和对于广义的前缀和来讲,是指前缀对后面产生了影响。同样的,我们也可以根据题意,对它进行一个反向的操作消除前面的影响,就像前缀和 a r ? a l ? 1 a_r-a_{l-1} ar??al?1?,前缀积 a r ? a l ? 1 p ? 2 a_r*a_{l-1}^{p-2} ar??al?1p?2?,一样,如果一个操作对后面所有的都会产生影响,并且我们需要查询任意一段区间的影响时,我们就可以通过广义前缀和的思想,通过一个反向操作取消前面的操作对结果的影响。从而得到某一区间的影响 ? 传送门 牛牛的猜球游戏题意有0~9十个小球分别装在十个瓶子中,有n次操作,每次操作选取其中两个瓶子并交换它们的位置,有q次询问,进行 l~r的操作,结果是多少 题解既然这道题已经指明了是用前缀和来思考,那么我们怎么样将它转化为前缀和问题呢 首先我们可以发现,它的某一个阶段的结果都是由前面的操作影响而来,并且这些影响相互叠加,我们求某一段的影响,就可以用 s u m r sum_r sumr?去掉前面 s u m l ? 1 sum_{l-1} suml?1?的影响,由前面广义前缀和的定义,我们就可以将这个问题转化为前缀和问题了 那么现在的问题就转化为怎么样消除影响了,假设
在经过若干次变化后变成了 ? 1 7 9 8 6 4 5 1 3 2 0 又经过若干次变化变成了 ? 2 6 7 9 8 3 4 1 2 0 5 如果我们这个时候是求**12**的影响,那么我们只需要将0式子进行12的变换,也就是将0-9以此填入1式子中的瓶子中,然后再2中的这些瓶子中的小球顺序,就是所求的小球顺序
补充前缀知识,矩阵 差分计算贡献 1.一个区间加上同一个值(一维差分) 2.一个区间加上一段连续的值(二维差分) 3.一个区间内加上一段连续的值的平方(三维差分) 一般的差分(求多项式)数学定理:任何一个n次多项式在做了n+1次差分之后都会变成一个常数 所以对于一个多项式,我们知道它的最高次项k后, 我们就可以做k+1次差分将这个序列变成一个常数, 然后再通过k+1次的前缀和求出它的值,但是这种只适用于指数较小的时候,指数大了之后这样就不是最优了。 当我们对一个比较低阶的多项式求和,类似 ∑ 1 n k 1 x 3 + k 2 x 2 + k 3 x + k 4 \sum_1^nk_1x^3+k_2x^2+k3x+k4 ∑1n?k1?x3+k2?x2+k3x+k4的时候,如果我们对于这个式子求四次差分,我们就可以讲它变成一个特殊的序列,这个序列是只有前面k位是非零,其他剩下的都是零 小w的糖果题意 小w和他的两位队友 t e i t o 、 t o k i t s u k a z e teito、tokitsukaze teito、tokitsukaze,他们让n个小朋友们排成一长排并且从左到右依次标号为1,2,3,4,5,6,7,8,9…n。三个人同时从 p o s pos pos开始将糖果发给 p o s pos pos及之后的人 t o k i t s u k a z e tokitsukaze tokitsukaze,她将会从一个位置 p o s pos pos开始,依次向右给每个人1个糖果。 t e i t o teito teito,他将会从一个位置 p o s pos pos开始,依次向右,他将会给他碰到的第一个人发1个糖果,给他碰到的第二个人发2个糖果,给他碰到的第三个人发3个糖果…碰到的第k个人发k个糖果,直到向右走到编号为n的人为止。 w i n t e r z z 1 winterzz1 winterzz1,他将会从一个位置 p o s pos pos开始,依次向右,它将会给他碰到的第一个人发1个糖果,给他碰到的第二个人发4个糖果,给他碰到的第三个人发9个糖果…碰到的第k个人发 k 2 k^2 k2个糖果直到向右走到编号为n的人为止。 发糖的福利一共进行了m轮,现在告诉你这m轮发糖的人和他们该轮发糖的起始位置 p o s pos pos,请你告诉我这m轮发糖结束后1到n每个人手中糖果的数量,为了避免这个数字过大,你只用输出每一个人手中糖的数量 m o d ? ? 1 0 9 + 7 mod??10^9+7 mod??109+7后的结果即可。 题解 t o k i t s u k a z e tokitsukaze tokitsukaze是将后面所有人手上的糖果都加上一, t e i t o teito teito是将后面所有人,第i个人手上的糖果增加i个, w i n t e r z z 1 winterzz1 winterzz1则是将后面所有人,第i个人手上的糖果增加 i 2 i^2 i2个 对于 t o k i t s u k a z e tokitsukaze tokitsukaze的方式,我们只需要将 p o s pos pos后面的都加上一就可以了,这个时候我们可以用一个差分来维护这个区间加的操作,然后是对于 t e i t o teito teito来讲,他发糖果的方式就像 f ( i ) = i f(i)=i f(i)=i一样,我们只需要进行两次差分,就可以得出一个 1 , 0 , 0 , 0... 1,0,0,0... 1,0,0,0...的序列,在后面求的时候我们也只需要对他进行两次前缀和,然后就可以加上了,最后是对于 w i n t e r z z 1 winterzz1 winterzz1来讲,他发糖果的方式是 f ( i ) = i 2 f(i)=i^2 f(i)=i2, 这个时候我们只需要进行对它进行三次差分,我们就可以得到 1 , 1 , 0 , 0 , 0 , 0 , 0... 1,1,0,0,0,0,0... 1,1,0,0,0,0,0...这样的序列,最后对他进行三次前缀和我们就可以得到加到每一个人身上的糖果数量了。
智乃的多项式题意 接下来会进行M{M}M次修改操作,每次将会给你一个k次多项式 f ( x ) = c 0 x k + c 1 x k ? 1 + . . . + c k ? 1 x 1 + c k f(x)=c_0x^k+c_1x^{k?1}+...+c_{k?1}x^1+c_k f(x)=c0?xk+c1?xk?1+...+ck?1?x1+ck?,以及一段需要操作的目标数组区间 [ l , r ] [l,r] [l,r]。 然后你需要对 a l + f ( 1 ) , a l + 1 + f ( 2 ) , . . . a_l+f(1),a_{l+1}+f(2),... al?+f(1),al+1?+f(2),...以此类推,也就是对目标区间的第一个数字加上一个f(1),第二个数字加上f(2)… 最后进行Q次查询,每次查询一个区间 [ l , r ] [l,r] [l,r]的和,由于数很大,所以我们需要对 1 0 9 + 7 10^9+7 109+7取模 题解 如果我们对一个k次的多项式进行 k + 1 k+1 k+1次差分之后,我们会得到一个前k项非零,其他项都为零的一个序列,那么我们再进行一次差分,我们会发现这个序列除了k之后第一个数变成不是零的数以外,其他的都是零,也就是说,我们对于一个k次的多项式,再进行了 k + 1 k+1 k+1以上的差分,我们会发现实际上并不会对我们的序列造成很大的影响。 那么回到这道题,给出的多项式的最高次是五次,那么我们可以直接对每一个多项式进行6次差分,然后将得到的序列加在数列中,需要注意的是,由于给定了范围,那么我们需要一种操作来消除对于范围之外的影响,那么这个时候我们就可以定义另外一个函数 g ( x ) g(x) g(x)来抵消范围之外的影响。最后对每一个序列进行7次前缀和,前六次是为了得到序列,最后一次就是简单的求和。
智乃酱的子集与超集前置知识S O S d p SOSdp SOSdp S O S d p SOSdp SOSdp和状态压缩比较像,都是将一个物体的集合用二进制来表示选或者不选,而如何用这个东西枚举出所有的子集呢 首先我们可以发现,我们可以通过枚举这个数二进制上所有的一,那么它一定是由它本身和另一个当前位位零,其它位全部相同的数转移而来, 比如10100,搜先我们枚举它的第一个一 ,它是由10100和00100转移而来,然后我们枚举第二个一,它是由10100和10000转移而来,而00100又是由00000和00100转移而来,因为我们每次枚举都会将此位为一的变成零然后转移,所以是不会重复的,并且对于每一个一我们都会枚举此位为零或者为一的状态,所以我们能做到不重不漏的全部枚举完。 超集与子集相反,是枚举它为零的状态 题意 给出N个数,表示物品的价值,然后给出M个询问,每个询问里面包括k个数,然后给出这些物品的编号,要我们求出包含这些物品的集合U,它的子集之和和它的超集之和 题解 我们可以先预处理出每一个位置的价格异或之和,然后处理出每一个位置的子集和超集之和,最后按照询问输出
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/28 2:48:48- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |