Description

  D博士对物理有着深入的研究,经典物理、天体物理、量子物理都有着以他的名字命名的定理。最近D博士着迷
于研究粒子运动的无规则性。对圣经深信不疑的他相信,上帝创造的任何事物必然是有序的、有理可循的,而不是
无规则的、混沌的。 经过长时间的研究,D博士找到了很多出现相当频繁的轨迹片断,他把这些轨迹片断储存在一
个很大的数据库内。他需要你帮助他写一个程序,对于一个给出的粒子运动轨迹,统计数据库中每个轨迹片断的出
现的次数。 为清楚起见,我们定义一个粒子的轨迹为二维平面上的一个点列(P1, P2, … PN)。点列P的一个子
列[i, j]定义为P中一段连续的子序列(Pi, Pi+1, … Pj)。点列P的一个子列[u, v]被称为点列Q = (Q1, Q2 … 
Qv-u+1)在P中的一次出现,当且仅当Q经过有限次的平移、旋转、翻转、放缩之后得到Q’满足Q’k = Pu+k-1(k =
 1 … u – v + 1)。 对平面X-Y进行四种操作的解释平移 设平移向量为(dx, dy),则任意点(x,y)平移后的结果
为(x+dx, y+dy) 旋转 设旋转角为t,则任意点(x,y)旋转后的结果为 (x cos t – y sin t, x sin t + y cos t)
 翻转 任意点(x,y) 翻转后的结果为(x, -y) 放缩 设放缩比例为p (p ≠ 0),则任意点(x,y)放缩后的结果为(px,
 py)

Input

  第一行两个整数N、M,分别描述待处理的粒子运动轨迹的点列大小与数据库内的轨迹片断个数。接下来M行依
次给出每个轨迹片断。每行先是一个正整数K,表示该轨迹片断点列的长度。然后2K个整数,依次描述点列中的K个
点的横坐标与纵坐标。接下来一行2N个整数,依次描述待处理的粒子运动轨迹的点列中N个点的横坐标与纵坐标。
注:输入中的每条轨迹中任意相邻两点不会相同。

Output

  应包含M行,依次给出每个片段在待处理运动轨迹中的出现次数。

在平移旋转翻转变换后图形与原图相似,每条轨迹相邻三点构成一个有向三角形,可以用三边边长平方的最简整数比以及转向共4个数表示,但转向会因翻转而取反
将三个点及以上轨迹片段建出ac自动机,把点列及翻转后的点列分别在ac自动机上跑一次然后沿fail树统计答案
若轨迹片段上所有点共线则会被算两次要去重,若轨迹片段不足三个点可以直接算出出现次数
#include<bits/stdc++.h>
const int N=;
char buf[],*ptr=buf-;
int _(){
int x=,f=,c=*++ptr;
while(c<)c=='-'&&(f=-),c=*++ptr;
while(c>)x=x*+c-,c=*++ptr;
return x*f;
}
int gcd(int a,int b){
for(int c;b;c=a,a=b,b=c%b);
return a;
}
int dis(int x,int y){
return x*x+y*y;
}
int n,m,x[N],y[N],e[N],ans[N];
bool re[N];
struct tri{
int a,b,c,d;
tri(int w){
int x1=x[w]-x[w-],y1=y[w]-y[w-],x2=x[w]-x[w+],y2=y[w]-y[w+];
a=dis(x1,y1);
b=dis(x2,y2);
c=dis(x1-x2,y1-y2);
int g=gcd(a,gcd(b,c));
if(g>)a/=g,b/=g,c/=g;
d=x1*y2-x2*y1;
d=d<?-:d>;
}
bool operator<(tri w)const{
return a!=w.a?a<w.a:b!=w.b?b<w.b:c!=w.c?c<w.c:d<w.d;
}
};
std::map<tri,int>nx[N];
int p=,fa[N],deg[N],t[N],q[N],ql=,qr=;
int main(){
buf[fread(buf,,sizeof(buf),stdin)]=;
n=_();m=_();
for(int i=;i<m;++i){
int c=_();
for(int j=;j<c;++j){
x[j]=_();y[j]=_();
}
if(c<)ans[i]=n+-c,re[i]=;
else{
int w=;
for(int j=;j<c;++j){
tri t(j-);
if(t.d)re[i]=;
if(nx[w].find(t)==nx[w].end())nx[w][t]=++p;
w=nx[w][t];
}
e[i]=w;
}
}
ql=qr=;q[++qr]=;
while(ql!=qr){
int w=q[++ql];
for(std::map<tri,int>::iterator it=nx[w].begin();it!=nx[w].end();++it){
int u=it->second,v=fa[w];
q[++qr]=u;
while(v&&nx[v].find(it->first)==nx[v].end())v=fa[v];
fa[u]=v?nx[v][it->first]:;
}
}
for(int i=;i<n;++i){
x[i]=_();y[i]=_();
}
int w=;
for(int i=;i<n;++i){
tri t(i-);
while(w&&nx[w].find(t)==nx[w].end())w=fa[w];
w=w?nx[w][t]:;
++::t[w];
}
for(int i=;i<n;++i)y[i]=-y[i];
w=;
for(int i=;i<n;++i){
tri t(i-);
while(w&&nx[w].find(t)==nx[w].end())w=fa[w];
w=w?nx[w][t]:;
++::t[w];
}
ql=qr=;
for(int i=;i<=p;++i)++deg[fa[i]];
for(int i=;i<=p;++i)if(!deg[i])q[++qr]=i;
deg[]=0x3f3f3f3f;
while(ql!=qr){
int w=q[++ql],f=fa[w];
t[f]+=t[w];
if(!--deg[f])q[++qr]=f;
}
for(int i=;i<m;++i)if(e[i])ans[i]=t[e[i]];
for(int i=;i<m;++i)printf("%d\n",re[i]?ans[i]:ans[i]>>);
return ;
}

bzoj1039: [ZJOI2008]无序运动Movement的更多相关文章

  1. [ZJOI2008]无序运动Movement

    Description D博士对物理有着深入的研究,经典物理.天体物理.量子物理都有着以他的名字命名的定理.最近D博士着迷于研究粒子运动的无规则性.对圣经深信不疑的他相信,上帝创造的任何事物必然是有序 ...

  2. bzoj 1030-1039

    1030 JSOI2007 文本生成器 AC自动机加DP即可. 1031 JSOI2007 字符加密Cipher 后缀数组即可. 1032 JSOI2007 祖码Zuma 数据有问题. 设\(f(l, ...

  3. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  4. BZOJ练习记

    决定从头到尾干一波BZOJ!可能会写没几题就停下吧,但还是想学学新姿势啦. 1001. [BeiJing2006]狼抓兔子 即求 $(1, 1)$ 到 $(n, m)$ 的最小割.跑 dinic 即可 ...

  5. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

  6. bzoj1036 [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 12646  Solved: 5085 [Subm ...

  7. BZOJ 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 14354  Solved: 5802 [Subm ...

  8. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

  9. 【BZOJ】【1040】【ZJOI2008】骑士

    树形DP/基环树DP 我掉坑掉了好多…… 这题图比较特殊,每个连通块都是一棵基环树(我一开始以为图是连通的了……sigh,我说为什么网上的题解都要累加ans……),那么对于一棵基环树,我们先dfs找到 ...

随机推荐

  1. Windows7+VS2010下OpenGL的环境配置

    http://johnhany.net/2014/01/environment-for-opengl-with-vs2010/ OpenGL(Open Graphics Library)是一个开放的. ...

  2. AJAX实现异步登录

    //代码较为简单,只是测试所用 1.html登录页面代码 <table> <tr> <td>用户名:</td> <td><input ...

  3. Kruskal算法

    1.基本思想:设无向连通网为G=(V, E),令G的最小生成树为T=(U, TE),其初态为U=V,TE={ },然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边.若被考察的边的两个顶点属于 ...

  4. IntelliJ怎么读?

    原来IntelliJ 的正确发音是 Intel  li  J. 周知.

  5. dwr和spring的整合

    1.dwr在spring配置文件的配置: <!-- 注意这里新增加的dwr tag, 为使其生效,文件头中要声明namespace --> <dwr:configuration /& ...

  6. theano中的scan用法

    scan函数是theano中的循环函数,相当于for loop.在读别人的代码时第一次看到,有点迷糊,不知道输入.输出怎么定义,网上也很少有example,大多数都是相互转载同一篇.所以,还是要看官方 ...

  7. JavaScript模块化编程

    为什么模块化很重要?因为有了模块,我们就可以更方便的使用别人的代码,想要什么功能,就加载什么模块. 万事都有规矩,就是规范化! 目前,通行的Javascript模块规范有两种: CommonJS和AM ...

  8. 集合视图 UICollectionView

    什么是UICollectionView UICollectionView是一种新的数据展示方式,简单来说可以把他理解成多列的UITableView(请一定注意这是UICollectionView的最最 ...

  9. Python数学函数

    1.Python数学函数 1.abs(x):取绝对值,内建函数 2.math.ceil(x):向上取整,在math模块中 3.cmp(x,y):如果 x < y ,返回-1:如果 x == y ...

  10. 第四篇T语言实例开发,自动加血

    游戏自动加血 基础知识复习 通过前面的学习了解以下内容: TC软件的基本使用 TC的基础语法 变量与常量 功能的使用 流程语句的使用 线程的基本使用 TC控件的基本使用 热键和按钮的事件功能 控件的数 ...