银河战舰

来源:互联网 发布:基本款t恤 知乎 编辑:程序博客网 时间:2024/04/28 03:51

https://nanti.jisuanke.com/t/16620

首先点(x,y)经过O操作之后坐标为(y,x),不知道这个的同学最多可以拿到30分

其次点(x,y)经过R操作之后坐标为(xcosa-ysina,xsina+ycosa),不知道这个的同学最多可以拿到60分

对于没有O,R操作的数据,对x,y坐标分别维护线段树,支持区间加,区间取反就可以了

对于没有R操作的数据,再维护一个区间x,y坐标是否对换的标记就好了

接着我们发现经过任何操作之后x,y坐标都发生的是线性的变换,所以考虑用矩阵乘法维护,维护一个大小为1*3的矩阵(x坐标,y坐标,1),然后就能发现所有的操作都可以写成矩阵的形式,然后线段树维护矩阵标记的乘积就好了

所有区间都是[1,n]的部分分是给不会线段树维护矩阵或者常数过大的同学准备的


#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define N 100010using namespace std;struct matrix{matrix(){memset(a,0,sizeof(a));a[0][0]=a[1][1]=a[2][2]=1;}double a[3][3];void print(){int i,j;for(i=0;i<3;i++){for(j=0;j<3;j++)cout<<a[i][j]<<' ';cout<<endl;}}};matrix operator *(const matrix &x,const matrix &y){matrix ret;memset(ret.a,0,sizeof(ret.a));int i,j,k;for(j=0;j<3;j++)for(k=0;k<3;k++)if(y.a[k][j]!=0)for(i=0;i<3;i++)ret.a[i][j]+=x.a[i][k]*y.a[k][j];return ret;}matrix w[N<<2],chg,st;double x[N],y[N],pi=acos(-1);void pud(int x){w[x<<1]=w[x<<1]*w[x];w[x<<1|1]=w[x<<1|1]*w[x];w[x]=st;}void change(int now,int l,int r,int ll,int rr){if(l==ll&&r==rr) {w[now]=w[now]*chg;return;}int mid=(l+r)>>1;pud(now);if(rr<=mid) change(now<<1,l,mid,ll,rr);else if(ll>mid) change(now<<1|1,mid+1,r,ll,rr);else change(now<<1,l,mid,ll,mid),change(now<<1|1,mid+1,r,mid+1,rr);}void dfs(int now,int l,int r,matrix M){M=w[now]*M;if(l==r){printf("%.2lf %.2lf\n",x[l]*M.a[0][0]+y[l]*M.a[1][0]+M.a[2][0],x[l]*M.a[0][1]+y[l]*M.a[1][1]+M.a[2][1]);return;}int mid=(l+r)>>1;dfs(now<<1,l,mid,M);dfs(now<<1|1,mid+1,r,M);}int main(){int n,m;int i,j,l,r;double p,q,a;char s[10];scanf("%d",&n);for(i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);scanf("%d",&m);while(m--){scanf("%s%d%d",s,&l,&r);if(s[0]=='M'){scanf("%lf%lf",&p,&q);chg=st;chg.a[2][0]=p;chg.a[2][1]=q;}else if(s[0]=='X'){chg=st;chg.a[1][1]=-1;}else if(s[0]=='Y'){chg=st;chg.a[0][0]=-1;}else if(s[0]=='O'){chg=st;chg.a[0][0]=chg.a[1][1]=0;chg.a[1][0]=chg.a[0][1]=1;}else{scanf("%lf",&a);chg=st;chg.a[0][0]=chg.a[1][1]=cos(a*pi/180);chg.a[1][0]=-sin(a*pi/180);chg.a[0][1]=sin(a*pi/180);}change(1,1,n,l,r);}dfs(1,1,n,st);}


原创粉丝点击