2017/8/8训练日记(继续图论算法|ω・`)顺便cf题解)

图论算法……算法算法…今天趁着昨天刚看的 floyd算法又a了两道题,下午又在cf的练习赛上水了前两个题,第四题怎么都出不来,难受;

codeforces 811

简单写一下题解吧,代码就不粘上了

第一题:

题意:Vladik和Valera分别有a和b个糖,然后从Vladik开始拿1个,然后轮到Valera拿2个,然后Vladik开始拿3个,然后轮到Valera拿4个.。。。。。最后谁不能拿输出谁


分析:数据范围1e9,直接暴力i从1开始,奇数a=a-i,偶数b=b-i,谁小于0输出名字,break;

虽然暴力但不会超时的,嘻嘻

第二题:

题意:给你n个数字(每个数字都不相同),m次询问,每次询问给你l,r,x,问你区间[l,r]从小到大排序之后,x位置数字是否变化


分析:数据范围较小,对于每次询问查找区间[l,r]内比位置x数字小的有多少个,如果等于x-l,输出Yes,否则输出No;(如果比x小的大于x-l,注意直接break,输出No)

第三题:

题意:
现在给你一个长度为N的序列,我们可以将一些子序列设定为一堆,其价值为这堆中每种数字的异或值。
总价值为子序列的值的加和。
我们要求分成子序列的部分假设包含了数字5,那么整个序列出现的数字5都必须被这个子序列所包含。
问最大价值。

思路:

很显然我们可以从左到右O(n^2)的去Dp.
设定dp【i】表示到位子i所获得的最大加和。
那么就有:dp【i】=max(dp【i】,dp【j】+w【j+1】【i】);
这里w【j+1】【i】就是子序列区间【j+1,i】的价值,如果其不能够构成一个子序列,那么我们设定其价值为-INF即可。

那么我们这里需要预处理一下可行子序列的价值。


做不出来主要是卡在数字异或那了,我是真没翻译出来他是怎么得出结果的;

异或运算法则是:相同为0不同为1 。
1异或0=1,然后再异或1等于0咯
即:1异或0异或1=0
或者 1异或1异或0=0

第四题:
题意:
给你一个n*m大小的图,你输出一个方向之后,系统反馈给你一个坐标,表示走完这步之后到的位子,我们需要在2*n*m步之内走到终点,问怎样走才行(多解输出任意一个即可)。
我们一开始的位子是(1,1),终点位子是“F”,‘*’表示不能走的位子,游戏开始的时候,有一些小伙伴比较调皮,会将U和D互换,就是说假设我们操作了U,但是实际是走到了D.或者也可能将L和R互换,当然也可能都没有互换过,当然也可能都互换过。
然你模拟整个过程。
思路:
预处理Bfs跑出来一个可行解,然后我们按照这个过程模拟的去走,如果发现下一步走到的位子和预期走到的位子不同,那么肯定这个被换过了,那么此时我们反过去走就行。

还有    fflush(stdout);没弄懂!!!!!!!!!

第五题:
题意:用公共边且颜色相同的两个块属于同一个连通块,每次询问一个区间中有多少个连通块块。

分析:

线段树+并查集 
比较基本的思路就是因为行数比较小所以可以对于每个区间的左右两列维护并查集。 
维护的东西必须保证在该区间中可以连通的两个位置的编号相同。 
两个区间合并的时候,将两个区间左右两列的编号在并查集中的父亲赋值成自己。如果两个区间相邻的位置颜色相同就用并查集合并起来,然后此时再从并查集中查询区间左右列的编号即可。 
也就是说我们每个区间的左右两列维护的是一个连通块的编号,合并的时候用并查集进行合并。 



明天争取a完那个专题fighting!

你可能感兴趣的:(2017年暑假训练日记)