idea

为了挽救我迷失的大脑,我决定在此开一个大坑。用来拓展思维。

1.给定一个序列,让找所有子区间中区间和是k的倍数的区间个数。n,k<=1e6

  1.1转化前缀和是正常思路

  1.2可能要思考。。。(我不会)发现前缀和相减是k的倍数就能得到区间和。

  1.3然后是简化,一般转化问题就是为了简化,转化成的模型一定要能简化。相减是k的倍数,相减是k的倍数。模k同余

  1.4然后简化完了。就是给定一个序列(前缀和序列),让你找模k同余的点对数。

  1.5其实还有一点,这个题用暴力是用不到k的范围的,一般是某个数的倍数的问题一旦给k不是什么1e9,就要考虑把它做下标。

  1.6开桶,O(n)找出模k的余数的点数,然后n*(n-1)/2就行了。

2.给定一个长度为n的0/1串,与m个操作,每个操作给定一个长度,选择一个此长度的区间0/1取反,求变为全0的最小次数,保证1的个数<=8,n<=40000

  2.1 1的个数令人直接想到状压,但是好像没法压

  2.2 首先问题在于,我如果压每个1是否存在的的话有些问题,因为这个0/1翻转可能导致多出来一堆1,而n的范围令人吃屎。

  2.3 需要转化使得原0/1串区间操作保证1的个数不增。既然是区间操作,那么何不想想前缀和和差分呢

  2.4 前缀和:这个是前缀异或和,它能统计有奇/偶数个1,如果原数组前缀有奇数个1,那么此处为1,否则为0。貌似1的个数也是k的范围,但是要注意,这种转化之所以不行,是因为区间反转能导致许多数改变,状态转移很乱。

  2.5 差分:这个是异或差分,它能统计某个数和前面是否一样。显然是2k级别,可以状压,然后想问题是否被简化,好像可以,因为每个数到底是什么是和前一个数有关的(差分),所以区间修改就改两头取反就能把区间都改过来(仿佛很像二维链表)。问题成功转化。

  2.6 一个序列上有一堆××,然后你要通过最少次数把它们全部消掉。之后就有两种情况,一种是两头分别是1/0,那么1可以走到0,代价是1次,然后两头都是1,那么可以认为1和1一起消失,代价也是1次,而这就是我们想要的。再多一句,为什么没有0和0,可以认为这是没有意义的,因为0代表和前面一样,那完全可以找到不一样的(1),然后把这一长段都修改,如果找不到,那证明都相等且都等于a[0],即都为0,不用改。

  2.7 可能会问,怎么选择最优的两个消掉而不是被别的消掉但是不优呢?预处理两两消掉的代价,然后DP即可,DP是处理出每一次消掉两个的所有情况的最优值,然后最优解可能从当前某一个不优的状态转移,不用多说吧。

3.关于只能贡献一次类(非状压思路)问题:比如说有个吃宝物的题(自己yy的),一种宝物只能加一次分,在一维序列上来回移动,某种宝物只会在某个时间掉落在某个位置。问最大分数,T(时间)<=2000,m<=10,(鸣谢skyh思路)

  3.1好像这是一个状压,因为每个宝物只能吃一次,再吃不能加分。那么我就得状压每个吃过的宝物集合来判断接下来的决策。

  3.2问题变一下,某种宝物在截至时间之前都可以吃,吃完就消失了。那么宝物数范围就可以提到100了,没法状压了。

  3.4考虑为什么会变,为什么不用状压了。我的理解是:题目可以贪心一下了。

  3.5性质:吃过的宝物一定连成一个区间,(除非到点了)。也就是说不存在我几个被吃过的宝物中间夹着一个没过时也没吃的宝物。

  3.6显然路过的时候我能吃就吃。并且不存在我走到一半没吃到宝物就往回走(显然是傻x)

  3.7那么把吃过的宝物区间端点代替状压吃过的宝物集合,里边都是没吃过或过时的,这样在区间内移动一定不加贡献,扩展区间(区间外移动)就是状态转移,加贡献。正确性显然。(思路 by skyh)<-(大神级人物)

  3.8$f[t][i][j]$表示t时刻在i区间为i,j的最大分数,$g[t][i][j]$表示t时刻在j区间为i,j的最大分数,转移就4句话

  

4.图论方案数:给定n个点,m条无向边,问m-2条边走两次,剩下2条走一次的方案数(不同方案为至少有一条次数不同)无重边有自环

  4.1发现性质,走两次等于没走,也就是说不存在我走两次到达了边的另一端的情况。

  4.2证明:唯一例外的情况就是这个边属于一个环,我走一遍环然后再多走一下这条边,然而发现环上其它边就不能在不经过这条边的情况下走两次了。矛盾了。

  4.3然后,似乎就好办了,走一次的边只能连在同一个点。首先,我们把图变成树,可以在dfs的时候遇到横向边先走一下再回来,不影响dfs但是横向边都已经被去掉了。

  4.4考虑有自环,每有一个自环,这个自环可以和任意条边组成经过一遍的。相当与在遍历图的搜索树上,把走一次的边作为割边,分开两边。额大概是这样>-<,旁边是分叉,然后左侧顶点出发,先遍历左子树再回来,每条边恰好经过两次,走过这条边,再遍历右子树,每条边走两次,走到那个自环所在的点的时候自己绕一次。可以证明对于任意边这都是是成立的。

  4.5环和环也可以,直接选择一个点为根,遍历整棵树,在走到某两个带自环的点的时候绕一下,不影响遍历。

  4.6结论就出来了,应该是$sum C_{du[i]}^{2}$(两边)+环数*边数+选两个环。

5.变相图论:这种题一旦看出来就比较简单了。先写一个吧,Water,在矩阵内,给定每个块的高度,矩阵外每个块的高度为零且无限大,问一场大雨过后,每个块的积水高度是多少。

  5.1 我也是不知道是怎么看出来的,但是我们先从暴力一点一点来。先说一下我的错解吧

  5.2我是把高度相同的放到一起编成一个联通块,然后找联通块边界的最低点就是该联通块的水位高度,如果比自己高就减,比自己低就是0。

  5.3其实hack很容易但是我不会改,比如说

        2 2 2 2 2 

        2 0 0 0 2

        2 0 1 0 2

        2 0 0 0 2

        2 2 2 2 2

  这样的话里边的0会找到1作为边界,然后高度就是1了,里边的一高度是0。

  5.4不会改的原因是不会发现它错在哪了。

  5.5它好像在往里找边界,并不是往外边流。边界在那边就往那边找。但是其实0找1,1找0,都不是最终的状态。

  5.6也许我能想到吧,每个点的水位高度,是它到边界外的路径上的最大值,但是路径有很多,我要找的是这些最大值的最小值。

  5.7搜寻一下学过的算法那些能处理这个问题,找最小的一条路径,跑DJ即可,只需重载一下路径计算方法,不是加和而是去max,可以证明是有结合律的。其实不难,分析性质,转化即可。

原文地址:https://www.cnblogs.com/starsing/p/11334542.html