一些新知识(未完全消化的)

整理:

目录:

未整理:

曼哈顿距离与契比雪夫距离

曼哈顿距离: d i s = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ dis = |x_1-x_2|+|y_1-y_2| dis=x1x2+y1y2
契比雪夫距离: d i s = m a x ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ∣ ) dis = max(|x_1-x_2|,|y_1-y_2|) dis=max(x1x2,y1y2)
两者相互转换:
曼哈顿距离域转成契比雪夫距离域: ( x , y ) ⇒ ( x + y , x − y ) (x,y)\Rightarrow(x+y,x-y) (x,y)(x+y,xy)
契比雪夫距离域转成曼哈顿距离域: ( x , y ) ⇒ ( x + y 2 , x − y 2 ) (x,y)\Rightarrow(\frac{x+y}{2},\frac{x-y}{2}) (x,y)(2x+y,2xy)
之后会更模拟退火(最小圆覆盖,球覆盖,以及wyz上的松鼠聚会)…

位运算(摘自usaco)

Binary

ValueSampleMeaning
x00101100the original x value
x & -x00000100extract lowest bit set
x | -x11111100create mask for lowest-set-bit & bits to its left
x ^ -x11111000create mask bits to left of lowest bit set
x & (x-1)00101000strip off lowest bit set
x | (x-1)00101111fill in all bits below lowest bit set
x ^ (x-1)00000111create mask for lowest-set-bit & bits to its right
~x & (x-1)00000011create mask for bits to right of lowest bit set
x | (x+1)00101101toggle lowest zero bit
x / (x&-x)00001011shift number right so lowest set bit is at bit 0

–> 避免遍历位操作,而是可以直接找到位的最低位,并对区间位进行O(1)运算。

对邻接表的进一步理解

在表示图的过程中我们会使用到邻接表这种数据结构,其中较为重要的一个操作便是加边操作。其伪代码为:

cnt = The number of edge having been added
procedure addedge(u,v,w)
{
	edge[v].v = v;
	edge[v].w = w;
	edge[v].next = head[u];
	head[u] = cnt++;
}

以前没好好理解这个 h e a d [ u ] = c n t head[u] = cnt head[u]=cnt++的问题,导致有次复杂图(相对于简单图)的次短路做不出来…
研究了一小会,邻接表为每个节点构建的链表有以下性质:

  • 1、对于某条从u出发的边而言,加入图中,则该头结点往后移动。所以在遍历节点链表的时候,是根据添边的顺序反向遍历的(最先加入的边的next指针指向-1)
  • 2、由第一条可知,head[u]存的是u节点链表中的最后一位,平常我们遍历的i值,其实是个指针,指向edge[i]这个节点,而edge[i].next也是一个指针。所以迭代的i作为指针,来依次访问链表中的edge[i]节点元素

完毕(另外spfa用双端队列优化的代码,其实在原spfa上改动不大,理解一下就好了)

测试网上评测的速度
//#define ONLINE_JUDGE
int main{
	#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long _begin_time = clock();
	#endif
	...//你的算法
	#ifndef ONLINE_JUDGE
    long _end_time = clock();
    printf("time = %ld ms.", _end_time - _begin_time);
	#endif
	return 0;
}

用的时候把数据存在文件里,把宏定义那一处删掉注销符号就好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值