链接:https://ac.nowcoder.com/acm/contest/160/D

来源:牛客网

整数序列

时间限制:C/C++ 2秒,其他语言4秒

空间限制:C/C++ 262144K,其他语言524288K

64bit IO Format: %lld

题目描述

给出一个长度为n的整数序列a1,a2,...,an,进行m次操作,操作分为两类。

操作1:给出l,r,v,将al,al+1,...,ar分别加上v;

操作2:给出l,r,询问\sum\limits_{i=l}^{r}sin(a_i)

i=l



r



sin(a

i



)

输入描述:

第一行一个整数n

接下来一行n个整数表示a1,a2,...,an

接下来一行一个整数m

接下来m行,每行表示一个操作,操作1表示为1 l r v,操作2表示为2 l r

保证1≤n,m,ai,v≤200000;1≤l≤r≤n,v是整数

输出描述:

对每个操作2,输出一行,表示答案,四舍五入保留一位小数

保证答案的绝对值大于0.1,且答案的准确值的小数点后第二位不是4或5

数据随机生成(n,m人工指定,其余整数在数据范围内均匀选取),并去除不满足条件的操作2

示例1

输入

复制

4

1 2 3 4

5

2 2 4

1 1 3 1

2 2 4

1 2 4 2

2 1 3

输出

复制

0.3

-1.4

-0.3

题意:



思路:



肯定会想到用线段树维护这样的操作,可是sin(xi)并不满足区间可加性。

转换一下

sin(x+v) = sin(x)cos(v) + cos(x)sin(v)

cos(x+v) = cos(x)cos(v) - sin(x)sin(v)

我们只需要维护sin(x) 和 cos(x) 就可以轻易的得到sin(x+v) 和 cos(x+v)

如果引入复数的:

cos(x)+sin(x)i ( cos(v)+sin(v)i ) = cos(x)cos(v)-sin(x)sin(v)+cos(x)sin(v)+sin(x)*cos(v) = cos(x+v)+sin(x+v)i


(此部分引用自)Uniontake的博客: https://blog.csdn.net/m0_38013346/article/details/81807711

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=200010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/ typedef complex<double> comd;
int a[maxn]; struct node
{
comd val;
comd add;
int l,r;
}segment_tree[maxn<<2];
int n;
void pushup(int rt)
{
segment_tree[rt].val=segment_tree[rt<<1].val+segment_tree[rt<<1|1].val; }
void build(int rt,int l,int r)
{
segment_tree[rt].add=comd(1,0);
segment_tree[rt].l=l;
segment_tree[rt].r=r;
if(l==r)
{
segment_tree[rt].val=comd(cos(a[l]),sin(a[l]));
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void pushdown(int rt)
{
if(segment_tree[rt].add!=comd(1,0))
{
segment_tree[rt<<1].add*=segment_tree[rt].add;
segment_tree[rt<<1].val*=segment_tree[rt].add;
segment_tree[rt<<1|1].add*=segment_tree[rt].add;
segment_tree[rt<<1|1].val*=segment_tree[rt].add;
segment_tree[rt].add=comd(1,0);
}
}
void update(int rt,int l,int r,comd x)
{
if(segment_tree[rt].l>=l&&segment_tree[rt].r<=r)
{
segment_tree[rt].val*=x;
segment_tree[rt].add*=x;
return ;
}
pushdown(rt);
int mid=(segment_tree[rt].l+segment_tree[rt].r)>>1;
if(mid>=l)
{
update(rt<<1,l,r,x);
}
if(mid<r)
{
update(rt<<1|1,l,r,x);
}
pushup(rt); }
double ask(int rt,int l,int r)
{
if(segment_tree[rt].l>=l&&segment_tree[rt].r<=r)
{
return segment_tree[rt].val.imag();
}
double res=0.0;
pushdown(rt);
int mid=(segment_tree[rt].l+segment_tree[rt].r)>>1;
if(mid>=l)
{
res+=ask(rt<<1,l,r);
}
if(mid<r)
{
res+=ask(rt<<1|1,l,r);
}
return res;
}
int main()
{
//freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
//freopen("D:\\common_text\\code_stream\\out.txt","w",stdout); gbtb;
cin>>n;
repd(i,1,n)
{
cin>>a[i];
}
build(1,1,n);
int m;
cin>>m;
int op,l,r;
int x;
while(m--)
{
cin>>op>>l>>r;
if(op==1)
{
cin>>x;
update(1,l,r,comd(cos(x),sin(x)));
}else
{
cout<<fixed<<setprecision(1)<<ask(1,l,r)<<endl;
}
} return 0;
} inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}

Wannafly挑战赛22 D 整数序列 (线段树维护三角函数值)的更多相关文章

  1. Wannafly 挑战赛22 D 整数序列 线段树 区间更新,区间查询

    题目链接:https://www.nowcoder.com/acm/contest/160/D 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524288K ...

  2. Wannafly挑战赛18 E 极差(线段树、单调栈)

    Wannafly挑战赛18 E 极差 题意 给出三个长度为n的正整数序列,一个区间[L,R]的价值定义为:三个序列中,这个区间的极差(最大值与最小值之差)的乘积. 求所有区间的价值之和.答案对\(2^ ...

  3. HDU 4521 小明系列问题——小明序列 (线段树维护DP)

    题目地址:HDU 4521 基本思路是DP.找前面数的最大值时能够用线段树来维护节省时间. 因为间隔要大于d. 所以能够用一个队列来延迟更新,来保证每次询问到的都是d个之前的. 代码例如以下: #in ...

  4. Wannafly挑战赛2 C.Butterfly(线段树优化枚举)

    题目链接  C.Butterfly 令$fd[i][j]$为以$s[i][j]$为起点开始往下走最大连续的‘X’个数 令$fl[i][j]$为以$s[i][j]$为起点开始往左下走最大连续的‘X’个数 ...

  5. Wannafly挑战赛22游记

    Wannafly挑战赛22游记 幸运的人都是相似的,不幸的人各有各的不幸. --题记 A-计数器 题目大意: 有一个计数器,计数器的初始值为\(0\),每次操作你可以把计数器的值加上\(a_1,a_2 ...

  6. Wannafly挑战赛22

    B. 字符路径 给一个含n个点m条边的有向无环图(允许重边,点用1到n的整数表示),每条边上有一个字符,问图上有几条路径满足路径上经过的边上的字符组成的的字符串去掉空格后以大写字母开头,句号 '.' ...

  7. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  8. bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...

  9. BZOJ1095 [ZJOI2007] Hide 捉迷藏 (括号序列 + 线段树)

    题意 给你一颗有 \(n\) 个点的树 , 共有 \(m\) 次操作 有两种类别qwq 将树上一个点染黑/白; 询问树上最远的两个黑点的距离. \((n \le 200000, m ≤500000)\ ...

随机推荐

  1. 国际标准 ISO 15008

    Road vehicles — Ergonomic aspects of transport information and control systems — Specifications and ...

  2. css(float浮动和clear清除)

    教程开始: 首先要知道,div是块级元素,在页面中独占一行,自上而下排列,也就是传说中的流.如下图: 可以看出,即使div1的宽度很小,页面中一行可以容下div1和div2,div2也不会排在div1 ...

  3. Java String.Format() 方法及参数说明

    转自:https://blueram.iteye.com/blog/441683 JDK1.5中,String类新增了一个很有用的静态方法String.format():format(Locale l ...

  4. opengl入门篇二: 索引缓冲对象EBO

    在绘制图形的过程中,顶点可能会重复.比如两个三角形组成了四边形,那么,必然有两个点是重复的.因此采用索引的方式,四个点即可描述四边形. // 四个顶点 GLfloat vertices[] = { / ...

  5. apache域名跳转

    状态码:*301: 永久重定向,域名跳转一定要用301,对搜索引擎友好的. 302:临时重定向在虚拟主机配置文件/usr/local/apache2/conf/extra/httpd-vhosts & ...

  6. 如何修改jar包的某一个class

    做了两年的开发,碰见了两次开源包的代码有问题,这次碰见的是wsdl4j.jar 具体问题以后再说,先说说如何修改其中的一个class 使用WinRAR打开(不是解压) 找到你要修改的class文件 右 ...

  7. sudo apt -y upgrade

    sudo apt -y upgrade     直接upgrade,不再询问y/n 但是如果是sudo apt-get install scilab -y 那么,就不再显示上图中的信息,即当安装包的时 ...

  8. The window object

    At the core of the BOM is the window object, which represents an instance of the browser. The window ...

  9. Platform区分不同平台

    用于区分平台 OS 属性 表示当前的平台类型.只有 ios 与 android 两个值.如可以使用为同一个属性在不同的平台上赋不同的值 const styles = StyleSheet.create ...

  10. python__007内置函数

    本文摘自:https://docs.python.org/3/library/functions.html?highlight=built#ascii     内置功能     abs() delat ...