\[\texttt{Preface}
\]

第二道 Ynoi 的题,纪念一下。

这可能是我唯一可以自己做的 Ynoi 题了。

\[\texttt{Description}
\]

维护一个长度为 \(n\) 的数列 \(a\),支持两种操作:

  • 1 l r v 将 \(a_l,a_{l+1},...,a_r\) 分别加上 \(v\)
  • 2 l r 询问 \(\sum\limits_{i=l}\limits^{r}\sin(a_i)\) 。

\[\texttt{Solution}
\]

  • 区间修改和区间查询使我们想到线段树。

  • 尝试在线段树上维护一个区间 \(\sin\) 和。

  • 我们发现,区间加的时候,原来的 \(\sin(a_i)\) 都变成了 \(\sin(a_i+v)\) ,不易直接维护。

  • 考虑这两个公式:

    \[\sin(a+v)=\sin a\cos v+\cos a\sin v
    \]

    \[\cos(a+v)=\cos a\cos v-\sin a \sin v
    \]

  • 显然区间加将区间 \([l,r]\) 的 \(\sin\) 和从 \(\sum\limits_{i=l}\limits^{r}\sin(a_i)\) 变成了 \(\sum\limits_{i=l}\limits^{r}\sin(a_i+v)\) ,进一步,有:

    \[\sum\limits_{i=l}\limits^{r}\sin a_i \cos v+ \cos a_i \sin v
    \]

\[\cos v \sum\limits_{i=l}\limits^{r}\sin a_i + \sin v\sum\limits_{i=l}\limits^{r}\cos a_i
\]

  • 于是我们可以再维护一个区间 \(\cos\) 和, 区间加对 \([l,r]\) 的 \(\cos\) 和的影响为:

\[\cos v \sum\limits_{i=l}\limits^{r} \cos a_i -\sin v\sum\limits_{i=l}\limits^{r} \sin a_i
\]

  • 套用上述公式更新区间 \(\sin\) 和以及区间 \(\cos\) 和即可,记得打好标记。

\[\texttt{Code}
\]

#include<cstdio>
#include<cmath> #define RI register int using namespace std; namespace IO
{
static char buf[1<<20],*fs,*ft;
inline char gc()
{
if(fs==ft)
{
ft=(fs=buf)+fread(buf,1,1<<20,stdin);
if(fs==ft)return EOF;
}
return *fs++;
}
#define gc() getchar()
inline int read()
{
int x=0,f=1;char s=gc();
while(s<'0'||s>'9'){if(s=='-')f=-f;s=gc();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=gc();}
return x*f;
}
}using IO::read; const int N=200100; int n,m; int a[N]; struct SegmentTree{
int l,r;
double sinv,cosv;
long long tag;
}t[N*4]; void upd(int p)
{
t[p].sinv=t[p*2].sinv+t[p*2+1].sinv;
t[p].cosv=t[p*2].cosv+t[p*2+1].cosv;
} void spread(int p)
{
if(t[p].tag)
{
double sina,cosa,sinx=sin(t[p].tag),cosx=cos(t[p].tag);
sina=t[p*2].sinv,cosa=t[p*2].cosv;
t[p*2].sinv=sina*cosx+cosa*sinx;
t[p*2].cosv=cosa*cosx-sina*sinx;
sina=t[p*2+1].sinv,cosa=t[p*2+1].cosv;
t[p*2+1].sinv=sina*cosx+cosa*sinx;
t[p*2+1].cosv=cosa*cosx-sina*sinx;
t[p*2].tag+=t[p].tag;
t[p*2+1].tag+=t[p].tag;
t[p].tag=0;
}
} void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
if(l==r)
{
t[p].sinv=sin(a[l]),t[p].cosv=cos(a[l]);
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
upd(p);
} void change(int p,int l,int r,int val)
{
if(l<=t[p].l&&t[p].r<=r)
{
double sina=t[p].sinv,cosa=t[p].cosv,sinx=sin(val),cosx=cos(val);
t[p].sinv=sina*cosx+cosa*sinx;
t[p].cosv=cosa*cosx-sina*sinx;
t[p].tag+=val;
return;
}
spread(p);
int mid=(t[p].l+t[p].r)/2;
if(l<=mid)
change(p*2,l,r,val);
if(mid<r)
change(p*2+1,l,r,val);
upd(p);
} double ask(int p,int l,int r)
{
if(l<=t[p].l&&t[p].r<=r)return t[p].sinv;
spread(p);
int mid=(t[p].l+t[p].r)/2;
double val=0;
if(l<=mid)
val+=ask(p*2,l,r);
if(mid<r)
val+=ask(p*2+1,l,r);
return val;
} int main()
{
n=read(); for(RI i=1;i<=n;i++)
a[i]=read(); build(1,1,n); m=read(); while(m--)
{
int opt=read(),l=read(),r=read(); switch(opt)
{
case 1:{ double val; scanf("%lf",&val);
change(1,l,r,val); break;
} case 2:{ printf("%.1lf\n",ask(1,l,r)); break;
}
}
} return 0;
}

\[\texttt{Thanks} \ \texttt{for} \ \texttt{watching}
\]

题解【[Ynoi2012]NOIP2015洋溢着希望】的更多相关文章

  1. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  2. [题解+总结]NOIP2015模拟题2

    // 此博文为迁移而来,写于2015年7月22日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w72i.html 1.总 ...

  3. 【题解】NOIP2015推销员

    ……普及组的题目都做不出来……(:´д`)ゞ……再这样下去要退役了啊…… 不过不管怎样感觉这题还是蛮好的,也要记录一下下~ 我们注意到数据的范围,n 是 1e5, 又有 1e5组询问,暴力大概是 \( ...

  4. 《如何在大学里脱颖而出(How to Win at College)》读书笔记

    <如何在大学里脱颖而出(How to Win at College)>读书笔记 图书简介 中文版: 英文版: 作者卡尔·纽波特(Cal Newport)于 2004 年6月以优等生荣誉学会 ...

  5. SDOI2017 BZOJ 4820 硬币游戏 解题报告

    写在前面 此题网上存在大量题解,但本人太菜了,看了不下10篇均未看懂,只好自己冷静分析了.本文将严格详细地论述算法(避免一切意会和玄学),因此可能会比其它题解更加理论化一些,希望能对像我一样看了其它题 ...

  6. 动态删边SPFA: [HNOI2014]道路堵塞

    [HNOI2014]道路堵塞 题目描述 $A$ 国有 $N$座城市,依次标为$1$到$N$.同时,在这$N$座城市间有$M$条单向道路,每条道路的长度是一个正整数.现在,$A$国交通部指定了一条从城市 ...

  7. 暑假集训D15总结

    考试 日常爆炸= = T1数据背锅,回天乏力 推了两个小时的T2竟然莫名RE,我也是服了 T3考试时就没读懂题,做个鬼啊 今天一直在写某奇怪的技术贴,竟然没有写题解(手动滑稽) 希望明天不要乱炸吧 博 ...

  8. LeetCode 31:递归、回溯、八皇后、全排列一篇文章全讲清楚

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天我们讲的是LeetCode的31题,这是一道非常经典的问题,经常会在面试当中遇到.在今天的文章当中除了关于题目的分析和解答之外,我们还会 ...

  9. [NOIP2015 提高组] 运输计划题解

    题目链接:P2680 [NOIP2015 提高组] 运输计划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 看了好长时间题解才终于懂的,有关lca和二分答案的题解解释的不详细,一时 ...

随机推荐

  1. 微信公众号获取access_token

    一般我们在进行微信公众号开发的时候,都需要用到access_token,但是具体的获取及其使用方式如何呢?下面展示一种获取的方式(具体的微信公众号申请和配置,请参考开放文档,具体在这里就不详细说明了) ...

  2. DP_1d1d诗人小G

    显然:f[i]=min{f[j]+(s[i]-s[j]+i-j-1-l)^p} 此题可以基于决策单调优化 证明,反正我现在不打算学 实际上就是双向队列 不停弹出队头的元素,直到当前位置在队头元素最优的 ...

  3. VUE常用写法

    v-for: v-for ='item,key of data' v-for ='item,index in data'     @click='' @click='pop.show=false'   ...

  4. Git - 后续

    1. 概述 现在讲了这些, 也就能应付一下日常的单机操作 后续大概会讲这些内容 分之间的 merge 本地仓库与远程仓库的互动

  5. 结构体sizeof()问题与字节对齐

    32位机器上定义如下结构体: struct xx { long long _x1; char _x2; int _x3; char _x4[2]; static int _x5; }; int xx: ...

  6. 【读书笔记】--《编写高质量iOS与OS X代码的52个有效方法》

    1.Objective-C 起源: 在 C 语言基础上添加了面向对象特性,是 C 语言的超集.Objective-C 由 SmallTalk 语言演变过来,使用消息结构,运行环境由运行环境决定. OC ...

  7. 69-for和if的嵌套使用

    #include <stdio.h> int main (void) { int i; ; ; i<=; ++i) { == )//%3==0 这个意思是i除以3,余数是0!说普通点 ...

  8. JavaScript 推箱子游戏

    推箱子游戏的 逻辑非常简单,但是如果不动手的话,还是不太清楚.我在这里讲一下自己的思路. 制作推箱子,首先要有自己的设计素材.如下我也是网上找的素材 第二步,理清游戏的规则. 游戏规则: 1.小人将箱 ...

  9. eclipse的版本代号

    mars为4.5版本号 代号 代号名 发布日期Eclipse 3.1 IO 木卫一,伊奥 2005Eclipse 3.2 Callisto 木卫四,卡里斯托 2006Eclipse 3.3 Europ ...

  10. HBase 2.1.3 集群 web 报错InvalidProtocolBufferException 解决方法

    搭建好HBase 集群后,各种后台进程都正常,搭建手册参考: Hbase 2.1.3 集群搭建手册https://www.cndba.cn/dave/article/3322 但是通过web访问,却报 ...