【问题描述】
    瑞奥和玛德利德是非常好的朋友。瑞奥平时的爱好是吹牛,玛德利德的爱好是戳穿瑞奥吹的牛。
    这天瑞奥和玛德利德来到了宇宙空间站,瑞奥向玛德利德炫耀这个空间站里所有的银河战舰都是自己的。整个空间站可以看成一个无限大的二维平面,而每个战舰都可以看做一个点,在空间站中一共分布着N艘银河战舰。
    玛德利德:“你说这些都是你的,那你让他们动一动啊”
瑞奥:“诶你看,那艘动了!”
    玛德利德:“操作指令由我来发,一共有5种动的方法……”
瑞奥:“我觉得这样有失公正……”
【输入格式】
第一行一个正整数N,表示战舰的数量
接下来N行,每行两个实数,代表第i个战舰的x,y坐标
然后一个正整数M,代表调度的次数
接下来M行操作,每个操作都是如下类型的一种:
M l r p q:把编号在[l,r]区间内的战舰x坐标加上p,y坐标加上q
X l r:把编号在[l,r]区间内的战舰沿x轴翻转
Y l r:把编号在[l,r]区间内的战舰沿y轴翻转
O l r:把编号在[l,r]区间内的战舰沿直线y=x翻转
R l r a:把编号在[l,r]区间内的战舰绕原点逆时针旋转a°
【输出格式】
输出包括N行,代表着N艘战舰经过M次调度之后的坐标(保留两位小数)
【样例输入】
3
1 2
-2 2.5
0 -3
3
X 1 3
M 1 3 3 6
R 1 3 90
【样例输出】
-4.00 4.00
-3.50 1.00
-9.00 3.00

用正常的线段树操作可以拿下M,X,Y,O操作大概是70分

但是R操作似乎无法实现

但此题我们发现它是离线的

那么只要有最后结果就行了

值得一提的是R操作(x,y)->(xcosa-ysina,xsina+ycosa)

用矩阵就可以了,转移矩阵:

cosa sina 0

-sina cosa 0

0      0       1

其实其他操作都可以用矩阵(上面矩阵不然为什么是3×3?)

假设状态(x,y,1),那么M操作转移矩阵:

1    0    0

0    1    0

p    q    1

1这个就是用来转移M操作的,那么其他操作也很简单了

用线段树维护矩阵标记,并下传就行了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct Matrix
{
double a[][];
Matrix()
{
memset(a,,sizeof(a));
a[][]=;a[][]=;a[][]=;
}
}Mat,c[],st;
double x[],y[];
char s[];
int n,m;
Matrix operator *(const Matrix &x,const Matrix &y)
{
Matrix res;
int i,j,k;
memset(res.a,,sizeof(res.a));
for (j=;j<=;j++)
{
for (k=;k<=;k++)
if (y.a[k][j])
{
for (i=;i<=;i++)
{
res.a[i][j]+=x.a[i][k]*y.a[k][j];
}
}
}
return res;
}
void pushdown(int rt)
{
c[rt*]=c[rt*]*c[rt];
c[rt*+]=c[rt*+]*c[rt];
c[rt]=st;
}
void update(int rt,int l,int r,int L,int R)
{
if (l>=L&&r<=R)
{
c[rt]=c[rt]*Mat;
return;
}
pushdown(rt);
int mid=(l+r)/;
if (L<=mid) update(rt*,l,mid,L,R);
if (R>mid) update(rt*+,mid+,r,L,R);
}
void dfs(int rt,int l,int r)
{
if (l==r)
{
printf("%.2lf %.2lf\n",x[l]*c[rt].a[][]+y[l]*c[rt].a[][]+c[rt].a[][],y[l]*c[rt].a[][]+x[l]*c[rt].a[][]+c[rt].a[][]);
return;
}
pushdown(rt);
int mid=(l+r)/;
dfs(rt*,l,mid);
dfs(rt*+,mid+,r);
}
int main()
{int i,j,l,r;
double p,q,a;
cin>>n;
for (i=;i<=n;i++)
{
scanf("%lf%lf",&x[i],&y[i]);
}
cin>>m;
for (i=;i<=m;i++)
{
scanf("%s",s);
scanf("%d%d",&l,&r);
if (s[]=='M')
{
scanf("%lf%lf",&p,&q);
memset(Mat.a,,sizeof(Mat.a));
Mat.a[][]=;Mat.a[][]=p;Mat.a[][]=;Mat.a[][]=q;
Mat.a[][]=;
update(,,n,l,r);
}
if (s[]=='X')
{
memset(Mat.a,,sizeof(Mat.a));
Mat.a[][]=-;Mat.a[][]=;Mat.a[][]=;
update(,,n,l,r);
}
if (s[]=='Y')
{
memset(Mat.a,,sizeof(Mat.a));
Mat.a[][]=;Mat.a[][]=-;Mat.a[][]=;
update(,,n,l,r);
}
if (s[]=='O')
{
memset(Mat.a,,sizeof(Mat.a));
Mat.a[][]=;Mat.a[][]=;Mat.a[][]=;
update(,,n,l,r);
}
if (s[]=='R')
{
memset(Mat.a,,sizeof(Mat.a));
scanf("%lf",&a);
Mat.a[][]=Mat.a[][]=cos(a*acos(-)/);
Mat.a[][]=sin(a*acos(-)/);
Mat.a[][]=-sin(a*acos(-)/);
Mat.a[][]=;
update(,,n,l,r);
}
}
dfs(,,n);
}
05-11 19:24