UVA 11768 - Lattice Point or Not(数论)

本文介绍了如何解决UVA11768-LatticePointorNot问题,通过将直线方程转换为整数形式并利用扩展欧几里得算法找出整数解的方法,特别考虑了特殊情况的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UVA 11768 - Lattice Point or Not

题目链接

题意:给定两个点,构成一条线段,这些点都是十分位形式的,求落在这个直线上的正数点。

思路:先把直线表达成a x + b y = c的形式,a,b, c都化为整数表示,然后利用扩展gcd求出x和y的通解,然后已知min(x1, x2) <= x <= max(x1, x2), min(y1, y2) <= y <= max(y1, y2),这样一来就可以求出通解中t的范围,t能取的整数就是整数解,就得到答案。

值得注意的是,直线为平行坐标系的情况,要特殊判断一下

代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;

const long long INF = 0x3f3f3f3f3f3f3f;
int t;
long long xx1, yy1, xx2, yy2;
long long a, b, c;

long long read(){
	double t;
	scanf("%lf", &t);
	return (long long)(10 * (t + 0.05));
}

long long gcd(long long a, long long b) {
	if (!b) return a;
	return gcd(b, a % b);
}

long long exgcd(long long a, long long b, long long &x, long long &y) {
	if (!b) {x = 1; y = 0; return a;}
	long long d = exgcd(b, a % b, y, x);
	y -= a / b * x;
	return d;
}

void build() {
	a = (yy2 - yy1) * 10;
	b = (xx1 - xx2) * 10;
	c = (yy2 - yy1) * xx1 + (xx1 - xx2) * yy1;
	long long t = gcd(gcd(a, b), c);
	a /= t; b /= t; c /= t;
}

long long solve() {
	long long ans = 0;
	long long x, y;
	long long d = exgcd(a, b, x, y);
	long long up = INF, down = -INF;
	if (xx1 > xx2) swap(xx1, xx2);
	if (yy1 > yy2) swap(yy1, yy2);
	if (c % d) return ans;
	if (b / d > 0) {
		down = max(down, (long long)ceil((xx1 * d * 1.0 / 10 - x * c * 1.0) / b));
		up = min(up, (long long)floor((xx2 * d * 1.0 / 10 - x * c * 1.0) / b));
 	}
 	else if (b / d < 0) {
 		up = min(up, (long long)floor((xx1 * d * 1.0 / 10 - x * c * 1.0) / b));
		down = max(down, (long long)ceil((xx2 * d * 1.0 / 10 - x * c * 1.0) / b));
  	}
  	else if (xx1 % 10) return ans;
  	if (a / d > 0) {
  		down = max(down, (long long)ceil((y * c * 1.0 - d * yy2 * 1.0 / 10) / a));
  		up = min(up, (long long)floor((y * c * 1.0 - d * yy1 * 1.0 / 10) / a));
   	}
   	else if (a / d < 0) {
   		up = min(up, (long long)floor((y * c * 1.0 - d * yy2 * 1.0 / 10) / a));
  		down = max(down, (long long)ceil((y * c * 1.0 - d * yy1 * 1.0 / 10) / a));
   	}
   	else if (yy1 % 10) return ans;
   	if (down <= up)
   		ans += up - down + 1;
	return ans;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		xx1 = read(); yy1 = read(); xx2 = read(); yy2 = read();
		build();
		printf("%lld\n", solve());
 	}
	return 0;
}


### Flat-Lattice 的概念 Flat-lattice 是一种用于处理自然语言处理任务的数据结构,特别是在涉及词典信息的任务中表现出色。这种结构能够将复杂的 lattice 展平成更易于处理的形式,同时保留原有的语义关系[^2]。 在具体实现方面,flat-lattice 可以定义为一组跨度(span),其中每个跨度代表一个标记(即字符或单词),并附带头部和尾部索引,用来指示该标记在原序列中的起始和结束位置。对于单个字符而言,其头部和尾部索引相同;而对于多字符组成的词语,则会记录下整个词语范围内的首尾位置。 ### Flat-Lattice 的实现方式 为了更好地理解 flat-lattice 如何运作,下面给出一段 Python 代码作为示例: ```python class Span: def __init__(self, start, end, label): self.start = start self.end = end self.label = label def build_flat_lattice(tokens, dictionary): spans = [] # 构建基于字面意思的初始span列表 for i, token in enumerate(tokens): span = Span(i, i+1, 'char') spans.append(span) # 添加来自词典的新spans for entry in dictionary.entries(): positions = find_sublist_positions(tokens, entry.tokens()) for pos in positions: new_span = Span(pos, pos+len(entry), entry.name) spans.append(new_span) return sorted(spans, key=lambda s: (s.start, -s.end)) ``` 此函数 `build_flat_lattice` 接收两个参数:一个是待分析的文本分词结果 `tokens` ,另一个是从外部加载得到的领域特定术语库 `dictionary` 。通过遍历这些输入数据,程序创建了一系列 Span 对象,并按照它们在原文档中的顺序进行了排序。 ### 应用场景 FLAT 模型利用了上述提到的 flat-lattice 结构,在 Transformer 编码器之上引入了一种新的位置编码机制,使得模型能够在不改变内部架构的情况下融入额外的知识源——比如预先编译好的词汇表。这种方法不仅提高了实体识别任务的表现精度,同时也保证了高效的 GPU 并行运算能力[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值