NOIP 2013 Day1
oier66Jia44you22!
P1 circle
(x+m*10k)%n
注意取模
P.S 这里是10k,所以也可以找循环节什么的。。。。。
P2 match
我就直接说解法了
首先我们离散化一下(姑且先这么叫),就是把两个数列按相应的大小关系都变成1~n的数。
然后我们把A数列变成1 2 3 4 5 ... n
那么这样就相当于有一个B数列,最少多少次相邻交换能变成A
容易发现对于B数列中的两个数 B[i] B[j],如果 B[i]<B[j] && i>j 那么这两个数就必然要交换。
那么依此就有两种可行的想法:
一、这是我比赛的时候的想法:首先在B中找到1,把它提到最前面,记录交换次数(就是对应的距离),然后提前2,累加次数,然后提前3... 以此类推。
照此模拟直接n2。因为每次移动了一堆没用的元素。
那么我们可以求出B中每个数到A中相应位置的距离。
我们发现每个元素的交换次数就是(它的距离)-(排在他后面但是比他小的元素个数)。
这个怎么求呢?多么简单啊!乱搞一下就可以了。
还是详细说一下吧
我们有一个数组ct[] ,初始全为1。
然后i=1->n扫描B数列,对于当前的数B[i],把 ct[i]变成0,然后比它小的数的个数就是ct[1]~ct[B[i]-1]的和
那么我们实质上是对于ct[],进行单点修改(每次ct[B[i]]-1),然后求区间和。
然后就怎么做都行了嘛。。。
树状数组最好写。因为本身求得就是从头开始的和,树状数组几行就行。
二、如果 B[i]<B[j] && i>j 那么这两个数就必然要交换。这不就是逆序对么?
这都想不到难道没学过逆序对么?
逆序对都不会那真是逗比啊
难道不会归并排序求逆序对么?不会用树状数组求逆序对么?
23333333 我也没想到
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑以上自嘲↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
其实刚才说的做法本质上就是用树状数组求逆序对。
我描述的应该应清晰了吧。。代码就不写了。。
P3 truck
我作了大死了,写二分最短路。。
然后我就死了。。
不作死就不会死。。。
目测30分?
先求最大生成树然后倍增LCA或者树链剖分。
也可以启发式合并。
这多显而易见那。。。果然不总做题就是不行。。。
希望不要犯什么逗比错误。。
以上。