kmjp's blog

競技プログラミング参加記です

yukicoder : No.1118 sin(x)/xの二乗和

前にもyukicoderで似たようなの出たけどね…。
https://yukicoder.me/problems/no/1118

問題

値xが与えられる。
 \displaystyle \sum_{j=0}^{\infty} \mathrm{sinc}^2(x+j)を求めよ。

解法

詳細はEditorialに書いてあるのでここでは解き方のみ。
愚直にsumを計算しようとしても、なかなか誤差が収束しない。

実は \displaystyle 
\sum_{j=0}^{\infty} \left(\frac{\sin(x+j)}{x+j}\right)^2 \approx \sum_{j=0}^{n} \left(\frac{\sin(x+j)}{x+j}\right)^2 + \frac{1}{2(x+n+1/2)}であり、後者の式でn=100000程度までループをすれば通る。
Editorialの別解にもあったけど、少し式変形すると誤差が急速に減少する形になるの、過去のyukicoderでもあったよね。

int N;
double X;
void solve() {
	int i,j,k,l,r,x,y; string s;
	
	cin>>X;
	N=100000;
	double ret=1.0/(2*(X+N+0.5));
	FOR(i,N+1) {
		if(X==0&&i==0) {
			ret+=1;
		}
		else {
			double a=sin(X+i)/(X+i);
			ret+=a*a;
		}
	}
	_P("%.12lf\n",ret);
}

まとめ

あんまり普通のコンテストで出なさそうなテクだけど、覚えておいた方がいいのかな。