记录编号 202702 评测结果 AAAAAAAAAA
题目名称 [SYOI 2015] Asm.Def的命令 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 10.125 s
提交时间 2015-11-01 20:59:49 内存使用 18.62 MiB
显示代码纯文本
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
using namespace std;
const int SIZEN=100010,SIZEC=3;
const double PI=4.0*atan(1.0),zero=1e-7;
class poi
{
public:
	int m,n;
	double s[SIZEC][SIZEC];
	poi()
	{
		m=n=0;
		memset(s,0,sizeof(s));
	}
	void make()
	{
		memset(s,0,sizeof(s));
		m=n=3;
		for(int i=0;i<n;i++) s[i][i]=1;
	}
	void make_cmd1(double x,double y)
	{
		memset(s,0,sizeof(s));
		n=m=3;
		s[0][0]=1,s[0][2]=x;
		s[1][1]=1,s[1][2]=y;
		s[2][2]=1;
	}
	void make_cmd2(int seg)
	{
		memset(s,0,sizeof(s));
		double now=seg/180.0*PI;
		double S=sin(now);
		double C=cos(now);
		n=m=3;
		s[0][0]=C,s[0][1]=-S,s[0][2]=0.0;
		s[1][0]=S,s[1][1]=C,s[1][2]=0.0;
		s[2][0]=0.0,s[2][1]=0.0,s[2][2]=1.0;
	}
	void print()
	{
		cout<<n<<" "<<m<<endl;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
				printf("%.1lf ",s[i][j]);
			cout<<endl;
		}
		cout<<endl;
	}
};
class miku
{
	public:
	int l,r;
	int left,right;
	poi G;
}tr[SIZEN*2];
int tot=1,N,q;
void built(int l,int r)
{
	int root=tot;
	tr[root].l=l,tr[root].r=r;
	tr[root].G.make();
	if(l==r)
	{
		tr[root].left=-1;tr[root].right=-1;
		tr[root].G.n=3;
		tr[root].G.m=1;
		tr[root].G.s[0][0]=0.0;
		tr[root].G.s[1][0]=(double)l+0.0;
		tr[root].G.s[2][0]=1.0;
		return;
	}
	int mid=(l+r)/2;
	tr[root].left=++tot;built(l,mid);
	tr[root].right=++tot;built(mid+1,r);
}
void read()
{
	scanf("%d%d",&N,&q);
	built(1,N);
}
poi operator * (poi a,poi b)
{
	poi c;
	c.m=b.m;
	c.n=a.n;
	for(int i=0;i<c.n;i++)
		for(int j=0;j<c.m;j++)
		{
			for(int k=0;k<a.m;k++)
				c.s[i][j]+=a.s[i][k]*b.s[k][j];
		}
	return c;
}
void push_down(int root)
{
	if(tr[root].left!=-1)
	{
		tr[tr[root].left].G=tr[root].G*tr[tr[root].left].G;
		tr[tr[root].right].G=tr[root].G*tr[tr[root].right].G;
		tr[root].G.make();
	}
}
void merge(int root,int st,int ed,poi P)
{
	push_down(root);
	if(ed<tr[root].l||st>tr[root].r) return;
	if(st<=tr[root].l&&ed>=tr[root].r)
	{
		tr[root].G=P*tr[root].G;
		return;
	}
	merge(tr[root].left,st,ed,P);
	merge(tr[root].right,st,ed,P);
}
poi get(int root,int st)
{
	push_down(root);
	if(tr[root].l==tr[root].r) return tr[root].G;
	int mid=(tr[root].l+tr[root].r)/2;
	if(st>mid) return get(tr[root].right,st);
	else return get(tr[root].left,st);
}
void work()
{
	int cmd=0;
	int st,ed;
	double c1,c2;
	int seg;
	poi G;
	for(int i=1;i<=q;i++)
	{
		scanf("%d",&cmd);
		if(cmd==0)
		{
			scanf("%d",&st);
			G.make();
			G=get(1,st);
			printf("%.1lf %.1lf\n",G.s[0][0],G.s[1][0]);
		}
		else if(cmd==1)
		{
			scanf("%d%d%lf%lf",&st,&ed,&c1,&c2);
			G.make_cmd1(c1,c2);
			//G.print();
			merge(1,st,ed,G);
		}
		else if(cmd==2)
		{
			scanf("%d%d%d",&st,&ed,&seg);
			G.make_cmd2(seg);
			//G.print();
			merge(1,st,ed,G);
		}
	}
}
int main()
{
	freopen("asm_command.in","r",stdin);
	freopen("asm_command.out","w",stdout);
	read();
	work();
	return 0;
}