[线段树]P6327 区间加区间 sin 和 题解

实际上知道了和差角公式这个题就好做了。

\[\sin(\alpha + \beta) = \sin(\alpha) \cos (\beta) + \cos(\alpha)\sin(\beta) \]

\[\cos(\alpha + \beta) = \cos(\alpha)\cos(\beta) - \sin(\alpha)\sin(\beta) \]

然后想一下怎么推到多个 \(\sin\) 的和。我们先不管第二个式子,只看第一个式子,看第一项,然后发现 \(\cos(\beta)\) 是个常量,那么直接乘法分配律就行。

其他同理。

\[\sum \sin (\alpha + \beta) = \cos(\beta)\sum \sin(\alpha) + \sin(\beta)\sum \cos(\alpha) \]

因此维护区间 \(\sin\)\(\cos\) 的和就行。还有就是要维护一下区间加的 \(lazy\) \(tag\)方便下传标记。

把下传的代码放一下吧。

void pushdown(int i) {
		if(plz[i]) {
  //Sin是区间sin和 , Cos是区间cos和 ,plz是加法的lazytag
			double s1 = Sin[i << 1] , c1 = Cos[i << 1];
			Sin[i << 1] = s1 * cos(plz[i]) + c1 * sin(plz[i]);
			Cos[i << 1] = c1 * cos(plz[i]) - s1 * sin(plz[i]);
			s1 = Sin[i << 1 | 1] , c1 = Cos[i << 1 | 1];
			Sin[i << 1 | 1] = s1 * cos(plz[i]) + c1 * sin(plz[i]);
			Cos[i << 1 | 1] = c1 * cos(plz[i]) - s1 * sin(plz[i]);
			plz[i << 1] += plz[i];
			plz[i << 1 | 1] += plz[i];
			plz[i] = 0;
		}
	}
posted @ 2025-04-29 20:38  「癔症」  阅读(28)  评论(0)    收藏  举报