您的位置:首页 > 大数据 > 人工智能

【 2013 Multi-University Training Contest 3 】

2013-08-01 00:14 344 查看
HDU 4622 Reincarnation

枚举字符串的起点,构造后缀自动机,每次插入一个字符,就能统计得到当前不同字串的个数,预处理出所有的询问。

#include<cstdio>
#include<set>
#include<iostream>
typedef long long LL;
#define MAXN 500010
#define oo 123456789123456789LL
using namespace std;
struct Point {
int x, y;
Point(int _x = 0, int _y = 0) {
x = _x;
y = _y;
}
friend bool operator<(Point a, Point b) {
if (a.x != b.x) {
return a.x < b.x;
} else {
return a.y < b.y;
}
}
};
set<Point> myset;
Point p[MAXN];
inline LL dis2(Point a, Point b) {
LL x = a.x - b.x;
LL y = a.y - b.y;
return x * x + y * y;
}
inline LL dis1(Point a, Point b) {
LL x = a.x - b.x;
return x * x;
}
int main() {
int T;
int n;
int ax, bx, cx;
int ay, by, cy;
LL ans, res;
set<Point>::iterator it, tmp;
scanf("%d", &T);
while (T--) {
scanf("%d%d%d%d%d%d%d", &n, &ax, &bx, &cx, &ay, &by, &cy);
p[0] = Point(bx % cx, by % cy);
for (int i = 1; i < n; i++) {
p[i] = Point((p[i - 1].x * (LL) ax + bx) % cx,
(p[i - 1].y * (LL) ay + by) % cy);
}
res = oo;
ans = 0;
myset.clear();
myset.insert(p[0]);
for (int i = 1; i < n; i++) {
if (myset.count(p[i])) {
break;
}
myset.insert(p[i]);
it = myset.find(p[i]);
for (tmp = it, ++tmp; tmp != myset.end(); ++tmp) {
if (dis1(*it, *tmp) >= res) {
break;
} else {
res = min(res, dis2(*it, *tmp));
}
}
if (it != myset.begin()) {
for (tmp = it, --tmp;; --tmp) {
if (dis1(*it, *tmp) >= res) {
break;
} else {
res = min(res, dis2(*it, *tmp));
}
if (tmp == myset.begin()) {
break;
}
}
}
ans += res;
}
cout << ans << endl;
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: