【2020NOI.AC省选模拟#2】A. 旋转
题目链接
原题解:
把每个点的坐标视为复数,那么每次询问就是区间求平均数(先求和然后除以个数)。一个点绕着原点旋转就是乘以$(\cos 60^\circ +i\sin 60^\circ)$。
一个点绕着某点$A$旋转可以理解为先减去点$A$的坐标,再绕原点旋转,再加上点$A$的坐标。
最终变成用线段树维护复数的序列,支持区间加上一个数和乘上一个数和区间求和,使用打标记的线段树解决。
补充:
在?为什么卡空间?
原题解提供的线段树做法很NICE,然而直接上线段树会被卡空间。然后我百度到了深度好文,学习了线段树少开空间的方法。
首先来个结论:
长度为$n$的序列会形成$2n-1$个节点的线段树。
为啥呢?观察一下线段树的结构,发现有底下的$n$个叶子,之后两个子节点用一个父节点合并。由$n$个连通块合并为一个块需要$n-1$次,所以总共有$2n-1$个节点。
然后我们考虑用DFS序给节点编号。 发现对于节点$i$代表$[l,r]$,左儿子的编号就是$i+1$,然后左子树占用了连续的$2(mid-l+1)-1$个编号,那么右儿子编号就是$i+2(mid-l+1)-1+1=i+2(mid-l+1)$。
然后就过了。打标记的线段树参考我自己的这篇博客。
噢还有一点,就是浮点数要记得重写一个等于函数,本题因为有封装,不容易注意到这个问题,但这确实会导致RE。
代码(100分):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define IL inline
#define RG register
#define _1 first
#define _2 second
using namespace std;
typedef double DB;
#define RI RG int
#define RD RG DB
#define RP RG Pr
#define RM RG Mrk
const int N=1e5;
const DB Pi=acos(-1);
const DB eps=1e-6; int n,q; struct Pr{
DB x,y;
Pr(RD x=0,RD y=0):x(x),y(y){}
}mul1=Pr(1,0),add0=Pr(0,0)
,rot=Pr(cos(Pi/3),sin(Pi/3))
,a[N+3],sum[N*2+3]; IL bool eql(RD x,RD y){
return fabs(x-y)<eps;
} IL bool operator==(RP x,RP y){
return eql(x.x,y.x)&&eql(x.y,y.y);
} IL Pr operator*(RP x,RP y){
return Pr(x.x*y.x-x.y*y.y,x.y*y.x+x.x*y.y);
} IL Pr operator*(RD x,RP y){
return Pr(x*y.x,x*y.y);
} IL Pr operator+(RP x,RP y){
return Pr(x.x+y.x,x.y+y.y);
} struct Mrk{
Pr m,a;
Mrk(RP m=mul1,RP a=add0):m(m),a(a){}
}non,tag[N*2+3]; IL bool operator==(RM x,RM y){
return x.m==y.m&&x.a==y.a;
} IL int ls(RI i){return i+1;}
IL int rs(RI i,RI l,RI mid){
return i+((mid-l+1)<<1);
} IL void f(RI i,RI l,RI r,RM opt){
if(opt==non)
return ; sum[i]=opt.m*sum[i]+(DB)(r-l+1)*opt.a; Mrk tmp=tag[i];
tag[i]=Mrk(opt.m*tmp.m,opt.m*tmp.a+opt.a); } IL void spread(RI i,RI l,RI r){
RI mid=(l+r)>>1;
f(ls(i),l,mid,tag[i]);
f(rs(i,l,mid),mid+1,r,tag[i]);
tag[i]=non; } void build(RI i,RI l,RI r){
tag[i]=non;
if(l==r){
sum[i]=a[l];
return ; } RI mid=(l+r)>>1;
build(ls(i),l,mid);
build(rs(i,l,mid),mid+1,r);
sum[i]=sum[ls(i)]+sum[rs(i,l,mid)]; } void mdf(RI i,RI l,RI r,RI ql,RI qr,RM opt){
if(ql<=l&&r<=qr){
f(i,l,r,opt);
return ; } spread(i,l,r);
RI mid=(l+r)>>1;
if(ql<=mid)
mdf(ls(i),l,mid,ql,qr,opt);
if(qr>mid)
mdf(rs(i,l,mid),mid+1,r,ql,qr,opt);
sum[i]=sum[ls(i)]+sum[rs(i,l,mid)]; } Pr qry(RI i,RI l,RI r,RI ql,RI qr){
if(qr<l||r<ql)
return add0;
if(ql<=l&&r<=qr)
return sum[i]; spread(i,l,r);
RI mid=(l+r)>>1;
if(qr<=mid)
return qry(ls(i),l,mid,ql,qr);
if(ql>mid)
return qry(rs(i,l,mid),mid+1,r,ql,qr);
return qry(ls(i),l,mid,ql,qr)
+qry(rs(i,l,mid),mid+1,r,ql,qr); } int main(){
scanf("%d%d",&n,&q);
for(RI i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y); build(1,1,n);
for(RI i=1,l,r;i<=q;i++){
scanf("%d%d",&l,&r); RP tmp=1.0/(r-l+1)*qry(1,1,n,l,r);
printf("%.10lf %.10lf\n",tmp.x,tmp.y);
mdf(1,1,n,l,r,Mrk(mul1,-1.0*tmp));
mdf(1,1,n,l,r,Mrk(rot,add0));
mdf(1,1,n,l,r,Mrk(mul1,tmp)); } for(RI i=1;i<=n;i++){
a[i]=qry(1,1,n,i,i);
printf("%.10lf %.10lf\n",a[i].x,a[i].y); } return 0; }
【2020NOI.AC省选模拟#2】A. 旋转的更多相关文章
- NOI.AC省选模拟赛第一场 T1 (树上高斯消元)
		link 很容易对于每个点列出式子 \(f_{x,y}=(f_{x,y-1}+f_{x,y}+f_{x,y+1}+f_{x+1,y})/4\)(边角转移类似,略) 这个转移是相互依赖的就gg了 不过你 ... 
- [NOI.AC省选模拟赛3.31] 星辰大海 [半平面交]
		题面 传送门 思路 懒得解释了......也是比较简单的结论 但是自己看到几何就退缩了...... 下周之内写一个计算几何的学习笔记! Code #include<iostream> #i ... 
- [NOI.AC省选模拟赛3.31] 附耳而至 [平面图+最小割]
		题面 传送门 思路 其实就是很明显的平面图模型. 不咕咕咕的平面图学习笔记 用最左转线求出对偶图的点,以及原图中每个边两侧的点是谁 建立网络流图: 源点连接至每一个对偶图点,权值为这个区域的光明能量 ... 
- [NOI.AC省选模拟赛3.30] Mas的童年 [二进制乱搞]
		题面 传送门 思路 这题其实蛮好想的......就是我考试的时候zz了,一直没有想到标记过的可以不再标记,总复杂度是$O(n)$ 首先我们求个前缀和,那么$ans_i=max(pre[j]+pre[i ... 
- [NOI.AC省选模拟赛3.23] 染色 [点分治+BFS序]
		题面 传送门 重要思想 真的是没想到,我很久以来一直以为总会有应用的$BFS$序,最终居然是以这种方式出现在题目中 笔记:$BFS$序可以用来处理限制点对距离的题目(综合点分树使用) 思路 本题中首先 ... 
- [NOI.AC省选模拟赛3.23] 集合 [数学]
		题面 传送门 一句话题意: 给定$n\leq 1e9,k\leq 1e7,T\leq 1e9$ 设全集$U=\lbrace 1,2,3,...n\rbrace $,求$(min_{x\in S}\lb ... 
- [noi.ac省选模拟赛]第12场题解集合
		题目 比赛界面. T1 数据范围明示直接\(O(n^2)\)计算,问题就在如何快速计算. 树上路径统计通常会用到差分方法.这里有两棵树,因此我们可以做"差分套差分",在 A 树上对 ... 
- [noi.ac省选模拟赛]第10场题解集合
		题目 比赛界面. T1 不难想到,对于一个与\(k\)根棍子连接的轨道,我们可以将它拆分成\(k+1\)个点,表示这条轨道不同的\(k+1\)段. 那么,棍子就成为了点与点之间的边.可以发现,按照棍子 ... 
- [noi.ac省选模拟赛]第11场题解集合
		题目 比赛界面. T1 比较简单.容易想到是求鱼竿的最大独立集.由于题目的鱼竿可以被分割为二分图,就可以想到最大匹配. 尝试建边之后会发现边的数量不小,但联系题目性质会发现对于一条鱼竿,它 ... 
- [noi.ac省选模拟赛20200606]赌怪
		题目 点这里看题目. 分析 先特判掉\(K=2\)的情况. 首先可以考虑到一个简单 DP : \(f(i)\):前\(i\)张牌的最大贡献. 转移可以\(O(n^2)\)地枚举区间 ... 
随机推荐
- HCIP-ICT实战进阶06-BGP基础
			HCIP-ICT实战进阶06-BGP基础 0 前言 运营商内部网络通过RIP.OSPF.ISIS实现网络互联, 但运营商之间要怎么办? 能不能互相引入路由? 理论上可行, 但考虑到网络机密问题和内部路 ... 
- dll帮助类
			项目中有很多时候用到外部dll,调用的时候如果用静态调用,程序exe目录下有很多dll,看起来很乱,不利于后续维护:动态调用可以把dll放在想放的文件夹内,但是如果一个dll要用到的函数很多,动态调用 ... 
- HIVE- INSERT 方法使用
			(1) INSERT INTOINSERT INTO tableVALUES ('aaa' , 111),('bbb' , 222); (2) insert overwrite insert over ... 
- Spring @aspect
			在 开发过程中,需要对每个 方法 执行时 进行日志 记录, 故而 整理一下, 有关 AOP 的 相关 知识点. 1. 切面类: @Aspect : 定义切面类, 加上 @Aspect,@Compo ... 
- 第十章用Python获取sqlite、MySQL、Excel、csv、json中的数据
			目录 获取sqlite3中的数据 sqlite3库获取sqlite数据 pandas库获取sqlite数据 获取MySQL中的数据 pymsql库获取MySQL数据 pandas库获取mysql数据 ... 
- Python学习的第四次总结
			修改文件内某行内容 f_read = open('文件名','r',encoding='utf-8')f_write = open('文件名1','w',encoding='utf-8')number ... 
- pycharm—python__________windows下安装
			参考地址:https://www.runoob.com/w3cnote/pycharm-windows-install.html 一.安装python 1.pip 和 setuptools ... 
- Zabbix源码安装与yum安装
			一.源码安装方式:zabbix-server LAMP环境准备: #groupadd zabbix#useradd -g zabbix zabbix 1.安装依赖包: #yum install gcc ... 
- vxlan结合iptables-snat实现内网服务器公网访问
			如上图,有这样一种场景,我们经常遇到,局域网内有两台服务器,Server 1和Server 2,Server 1可以通通网,Server 2只能通内网,无法直接访问公网 现在想Server 2能访问到 ... 
- vue资料链接
			vue 官方api:https://cn.vuejs.org/ vue资源精选:http://vue.awesometiny.com/ vue GitHub地址:https://github.com/ ... 
 
			
		