<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xml:lang="ja">
	<channel>
		<title>kojingharangの日記</title>
		<link>http://topcoder.g.hatena.ne.jp/kojingharang/</link>
		<description>kojingharangの日記</description>
		<dc:creator>kojingharang</dc:creator>


		<item>
			<title> SRM 719 Div1 500 OwaskiAndTree</title>
			<link>https://topcoder.g.hatena.ne.jp/kojingharang/20170815#1502794978</link>

			<description><![CDATA[
		<div class="section">
			<ul>
				<li> 1000頂点までの木が与えられる。頂点0から順に辺で行けるとこを何回でも移動できる。</li>
				<li> 頂点 i を最初に訪れたときスコアに pleasure[i] in [-10^6, 10^6] が足される。スコアが負になったら自動的に0まで回復する。</li>
				<li> スコアの最大値を求めよ。</li>
			</ul>
			<ul>
				<li> 木<a class="keyword" href="https://topcoder.g.hatena.ne.jp/keyword/DP">DP</a>ぽい</li>
				<li> (頂点, そこにくる直前のスコア) → 最良スコア は無理</li>
				<li> (頂点, 直前のスコアが0 or 十分大きい) → スコア(?) みたいな感じでいけないか</li>
				<li> なんかだめだ</li>
			</ul>
			<ul>
				<li> おわり</li>
			</ul>
			<p>(あとで)</p>
			<p><blockquote class="twitter-tweet"><p lang="ja">medは得点が負にならない能力のかわりに得点を1回だけ0点にできる能力をもってると考えてもよくて、木を「能力発動前に到達」「能力発動後に到達」「行かず」の3色に塗り分けることを考えて、木<a class="keyword" href="https://topcoder.g.hatena.ne.jp/keyword/DP">DP</a></p>&#8212; ちゃっくに300円 (@yosupot) <a href="https://twitter.com/yosupot/status/897288105517920256">2017年8月15日</a></blockquote></p>
			<p><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
			<p>これ見たときは「は？？」という感想だったが、よーく考えてみると分かった。</p>
			<h4> 必要な考察</h4>
			<ul>
				<li> 問題のルールに従うと、頂点 v0 → v1 → v2 → ... と辿ったときスコアの計算は以下のようになる。</li>
			</ul>
			<blockquote>
			<p>(あ) v0 → 操作A → v1 → 操作A → v2 → 操作A → v3 ... → 操作A</p>
			<p>操作A : スコアが負なら 0 にする</p>
			</blockquote>
			<ul>
				<li> この値は、以下の計算方法で求まるスコアの最大値と同じになる。</li>
			</ul>
			<blockquote>
			<p>(い) 操作B → v0 → 操作B → v1 → 操作B → v2 → 操作B → v3 ... → 操作B</p>
			<p>操作B : スコアを 0 にリセットすることができる</p>
			</blockquote>
			<ul>
				<li> 理由: 操作Bのとき、スコアが負ならリセット、正ならリセットしなければ (あ) と一致する</li>
			</ul>
			<ul>
				<li> さらにこれは以下の最大値と等しい。</li>
			</ul>
			<blockquote>
			<p>(う) 操作B → v0 → 操作B → v1 → 操作B → v2 → 操作B → v3 ... → 操作B  ※ただしリセットは高々 1 回だけ</p>
			</blockquote>
			<ul>
				<li> 理由: もしあれば、(う) のリセットポイントを (い) の最後のリセットポイントと同じにすれば、最後以外はリセットしなくても同じなので (い) と一致する</li>
			</ul>
			<h4> ということで</h4>
			<ul>
				<li> 全頂点は「最初に訪れた時リセット前」「最初に訪れた時リセット後」「訪れない」に分類できる。</li>
				<li> それぞれ BR, AR, NONE と書く。</li>
				<li> リセットしない場合は最初にリセットすると考えて全頂点が AR or NONE である状態に対応する。</li>
				<li> 最後にリセットする場合は全頂点が BR or NONE である状態に対応する。</li>
			</ul>
			<ul>
				<li> あとは、以下を求めていけば max ( f(0, BR), f(0, AR) ) が答えとなる。</li>
			</ul>
			<blockquote>
			<p>f(頂点 v, v の状態) = v 以下のサブツリーのスコアの最大値</p>
			</blockquote>			<br>

			<blockquote>
			<p>(v, AR) = v でリセット後ということはその子ノードは訪れないかリセット後じゃないといけないので pleasure[v] + Σ f(子ノード, AR|NONE)</p>
			<p>(v, NONE) = 子ノードも全部 NONE なので 0</p>
			<p>(v, BR) = pleasure[v] はどうせリセットされるのでカウントしない。各子ノードは AR でも BR でも NONE でもよいので Σ f(子ノード, BR|AR|NONE)</p>
			</blockquote>
			<p>ほう〜 こんなすっきりとなるのか〜</p>
			<p>(accepted in practice)</p>
<pre class="syntax-highlight">
<span class="synType">class</span> OwaskiAndTree {
	<span class="synStatement">public</span>:
	<span class="synType">int</span> maximalScore(vector &amp;#<span class="synConstant">60</span>;<span class="synType">int</span>&amp;#<span class="synConstant">62</span>; pa, vector &amp;#<span class="synConstant">60</span>;<span class="synType">int</span>&amp;#<span class="synConstant">62</span>; pl) {
		<span class="synType">int</span> N = pa.size()+<span class="synConstant">1</span>;
		VI br(N);
		VI ar(N);
		<span class="synComment">// 葉から順に配ると簡潔に書ける ... lhic さんの実装を参考にした</span>
		<span class="synStatement">for</span>(<span class="synType">int</span> i=N-<span class="synConstant">1</span>; i&amp;#<span class="synConstant">62</span>;=<span class="synConstant">0</span>; i--) {
			ar[i] += pl[i];
			ar[i] = max(ar[i], <span class="synConstant">0LL</span>);
			<span class="synStatement">if</span>(i) {
				<span class="synType">int</span> pi = pa[i-<span class="synConstant">1</span>];
				ar[pi] += ar[i];
				br[pi] += max(br[i], ar[i]);
			}
		}
		<span class="synStatement">return</span> max(br[<span class="synConstant">0</span>], ar[<span class="synConstant">0</span>]);
	}
};
</pre>

			<p class="share-button sectionfooter"><a href="http://b.hatena.ne.jp/entry/https://topcoder.g.hatena.ne.jp/kojingharang/%23" class="hatena-bookmark-button" data-hatena-bookmark-title="2017-08-15" data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加"><img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a><script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script><a href="http://twitter.com/share" class="twitter-share-button" data-lang="ja" data-count="none" data-url="https://topcoder.g.hatena.ne.jp/kojingharang/#" data-text="2017-08-15 - kojingharangの日記 (id:kojingharang)">ツイートする</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js" charset="utf-8"></script><iframe src="http://www.facebook.com/plugins/like.php?href=https%3A%2F%2Ftopcoder.g.hatena.ne.jp%2Fkojingharang%2F%23&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:21px;" allowTransparency="true"></iframe></p>

		</div>
]]></description>

			<dc:creator>kojingharang</dc:creator>

			<pubDate>Tue, 15 Aug 2017 11:02:58 GMT</pubDate>



		</item>

		<item>
			<title> Codeforces #412 Mister B and PR Shifts (Div2 D, Div1 B)</title>
			<link>https://topcoder.g.hatena.ne.jp/kojingharang/20170628#1498643481</link>

			<description><![CDATA[
		<div class="section">
			<ul>
				<li> [1, N] の permutation が与えられる。</li>
				<li> Σ^{N}_{1} |rotate_right(p, j)[i]-i| の最小値とそのときの j を求めよ。</li>
				<li> 2≦N≦10^6</li>
			</ul>
			<ul>
				<li> すごく規則性がありそう</li>
				<li> N^2 で実装して実験くん</li>
				<li> N=10で適当な例を試したら広義単調増加→減少となめらかに変わってそうなので三分探索</li>
				<li> 三分探索初めて書くので非常に怪しい</li>
				<li> <a class="keyword" href="https://topcoder.g.hatena.ne.jp/keyword/WA">WA</a></li>
			</ul>
			<p>(あとで)</p>
			<ul>
				<li> N = 1000 くらいでランダムケースを見てみたら全然なめらかに変わってなかった...</li>
				<li> ちょっとずつずらしたときに某値とその変化量がどれくらい変わるかを最初に O(N) で求めておいて O(N) でちょっとずつずらしていくやり方があるようだ。</li>
				<li> 書いてみるが超絶ムズい...</li>
				<li> なんとか通ったけど +1 -1 とか不等号に等号が付くかとか場合分けとか無限にバグる要素ある。</li>
			</ul>
			<p>(accepted in practice)</p>
<pre class="syntax-highlight">
<span class="synType">void</span> solve(ll N, <span class="synType">const</span> VI&amp;#<span class="synConstant">38</span>; w, ll&amp;#<span class="synConstant">38</span>; minVar, ll&amp;#<span class="synConstant">38</span>; ans) {
	VI varDiff(N+<span class="synConstant">10</span>), deltaDiff(N+<span class="synConstant">10</span>);
	ll var = <span class="synConstant">0</span>;
	REP(i, N) {
		VI&amp;#<span class="synConstant">38</span>; dd = deltaDiff;
		<span class="synComment">// 無限にバグるパート</span>
		<span class="synStatement">if</span>(w[i]&amp;#<span class="synConstant">62</span>;i+<span class="synConstant">1</span>) {
			<span class="synComment">// 最初 -1 で idx1 のときに +1 になる. また idx3 で -1 になる</span>
			dd[<span class="synConstant">0</span>] += -<span class="synConstant">1</span>;

			<span class="synType">int</span> idx1 = w[i]-(i+<span class="synConstant">1</span>);
			dd[idx1] += +<span class="synConstant">2</span>;

			<span class="synType">int</span> idx3 = N-(i+<span class="synConstant">1</span>)+<span class="synConstant">1</span>;
			dd[idx3] += -<span class="synConstant">2</span>;
		} <span class="synStatement">else</span> {
			<span class="synComment">// 最初 +1 で idx1 のときに -1 になる. また idx3 で +1 になる</span>
			dd[<span class="synConstant">0</span>] += +<span class="synConstant">1</span>;

			<span class="synType">int</span> idx1 = N-((i+<span class="synConstant">1</span>)-w[i]);
			dd[idx1] += +<span class="synConstant">2</span>;

			<span class="synType">int</span> idx3 = N-(i+<span class="synConstant">1</span>)+<span class="synConstant">1</span>;
			dd[idx3] += -<span class="synConstant">2</span>;
		}

		{
			<span class="synComment">// 回転した瞬間に var が調整される</span>
			<span class="synType">int</span> idx = N-(i+<span class="synConstant">1</span>)+<span class="synConstant">1</span>;
			ll v = -(N-(w[i]-<span class="synConstant">1</span>)) + (w[i]-<span class="synConstant">1</span>);
			varDiff[idx] += v;
		}
		var += abs(w[i]-(i+<span class="synConstant">1</span>));
	}
	minVar = var;
	ans = <span class="synConstant">0</span>;
	ll delta = deltaDiff[<span class="synConstant">0</span>];
	RANGE(i, <span class="synConstant">1</span>, N) {
		var += varDiff[i] + delta;
		delta += deltaDiff[i];
		<span class="synStatement">if</span>(var&amp;#<span class="synConstant">60</span>;minVar) {
			minVar = var;
			ans = i;
		}
	}
}


<span class="synType">int</span> main() {
	ios::sync_with_stdio(<span class="synConstant">false</span>);
	ll N;
	<span class="synStatement">while</span>(cin&amp;#<span class="synConstant">62</span>;&amp;#<span class="synConstant">62</span>;N) {
		VI w(N);
		REP(i, N) cin&amp;#<span class="synConstant">62</span>;&amp;#<span class="synConstant">62</span>;w[i];
		ll minVar, ans;
		solve(N, w, minVar, ans);
		cout&amp;#<span class="synConstant">60</span>;&amp;#<span class="synConstant">60</span>;minVar&amp;#<span class="synConstant">60</span>;&amp;#<span class="synConstant">60</span>;<span class="synConstant">&quot; &quot;</span>&amp;#<span class="synConstant">60</span>;&amp;#<span class="synConstant">60</span>;ans&amp;#<span class="synConstant">60</span>;&amp;#<span class="synConstant">60</span>;endl;
	}
	
	<span class="synStatement">return</span> <span class="synConstant">0</span>;
}
</pre>
			<br>

			<p>おまけ: メモ</p>
<pre class="syntax-highlight">
<span class="synComment">/*</span>
<span class="synComment">方針:</span>

<span class="synComment">変化量 = 0</span>
<span class="synComment">varDiff[i]: i 回目の始めに var が変化する分.</span>
<span class="synComment">deltaDiff[i]: i 回目の始めに変化量が変化する分</span>
<span class="synComment">var = rot0でのスコア</span>
<span class="synComment">loop</span>
<span class="synComment">	var += 変化量 + varDiff[i]</span>
<span class="synComment">	変化量 += deltaDiff[i]</span>


<span class="synComment">5</span>
<span class="synComment">5 4 3 2 1</span>
<span class="synComment">での想定動作</span>

<span class="synComment">0</span>
<span class="synComment">	-1 -1 -1 -1  1</span>
<span class="synComment">	deltaDiff</span>
<span class="synComment">	-1  0  0  0  1</span>
<span class="synComment">1</span>
<span class="synComment">	-1 -1  1  1 -1</span>
<span class="synComment">	deltaDiff</span>
<span class="synComment">	-1  0  2  0 -2</span>
<span class="synComment">2</span>
<span class="synComment">	 1  1  1 -1 -1</span>
<span class="synComment">	deltaDiff</span>
<span class="synComment">	 1  0  0 -2  0</span>
<span class="synComment">3</span>
<span class="synComment">	 1  1 -1  1  1</span>
<span class="synComment">	deltaDiff</span>
<span class="synComment">	 1  0 -2  2  0</span>
<span class="synComment">4</span>
<span class="synComment">	 1  1  1  1  1</span>
<span class="synComment">	deltaDiff</span>
<span class="synComment">	 1  0  0  0  0</span>

<span class="synComment">sum</span>
<span class="synComment">	 1  1  1  1  1</span>



<span class="synComment">12</span>
<span class="synComment">8</span>
<span class="synComment">	12 += -5 +1</span>
<span class="synComment">6</span>
<span class="synComment">	8 += -3 +1</span>
<span class="synComment">6</span>
<span class="synComment">	6 += -1 +1</span>
<span class="synComment">8</span>
<span class="synComment">	6 += +1 +1</span>


<span class="synComment">0</span>
<span class="synComment">	p   o</span>
<span class="synComment">	 p o</span>
<span class="synComment">	  p</span>
<span class="synComment">	 o p</span>
<span class="synComment">	o   p</span>

<span class="synComment">	delta</span>
<span class="synComment">		0 -1</span>
<span class="synComment">		1 -1</span>
<span class="synComment">		2  1</span>
<span class="synComment">		3  1</span>
<span class="synComment">		4  1</span>
<span class="synComment">		sum 1</span>

<span class="synComment">1</span>
<span class="synComment">	 p  o</span>
<span class="synComment">	  po</span>
<span class="synComment">	  op</span>
<span class="synComment">	 o  p</span>
<span class="synComment">	p</span>

<span class="synComment">	delta</span>
<span class="synComment">		0 -1</span>
<span class="synComment">		1 -1</span>
<span class="synComment">		2  1</span>
<span class="synComment">		3  1</span>
<span class="synComment">		4  1</span>
<span class="synComment">		sum 1</span>

<span class="synComment">2</span>
<span class="synComment">	  p o</span>
<span class="synComment">	   p</span>
<span class="synComment">	  o p</span>
<span class="synComment">	po   </span>
<span class="synComment">	op</span>

<span class="synComment">	delta</span>
<span class="synComment">		0 -1</span>
<span class="synComment">		1  1</span>
<span class="synComment">		2  1</span>
<span class="synComment">		3 -1</span>
<span class="synComment">		4  1</span>
<span class="synComment">		sum 1</span>

<span class="synComment">3</span>
<span class="synComment">	   po</span>
<span class="synComment">	   op</span>
<span class="synComment">	p o  </span>
<span class="synComment">	 p   </span>
<span class="synComment">	o p</span>

<span class="synComment">	delta</span>
<span class="synComment">		0 -1</span>
<span class="synComment">		1  1</span>
<span class="synComment">		2 -1</span>
<span class="synComment">		3  1</span>
<span class="synComment">		4  1</span>
<span class="synComment">		sum 1</span>

<span class="synComment">4</span>
<span class="synComment">		p</span>
<span class="synComment">	p  o </span>
<span class="synComment">	 po  </span>
<span class="synComment">	 op  </span>
<span class="synComment">	o  p</span>

<span class="synComment">	delta</span>
<span class="synComment">		0  1</span>
<span class="synComment">		1 -1</span>
<span class="synComment">		2 -1</span>
<span class="synComment">		3  1</span>
<span class="synComment">		4  1</span>
<span class="synComment">		sum 1</span>

<span class="synComment">*/</span>
</pre>

			<p class="share-button sectionfooter"><a href="http://b.hatena.ne.jp/entry/https://topcoder.g.hatena.ne.jp/kojingharang/%23" class="hatena-bookmark-button" data-hatena-bookmark-title="2017-06-28" data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加"><img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a><script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script><a href="http://twitter.com/share" class="twitter-share-button" data-lang="ja" data-count="none" data-url="https://topcoder.g.hatena.ne.jp/kojingharang/#" data-text="2017-06-28 - kojingharangの日記 (id:kojingharang)">ツイートする</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js" charset="utf-8"></script><iframe src="http://www.facebook.com/plugins/like.php?href=https%3A%2F%2Ftopcoder.g.hatena.ne.jp%2Fkojingharang%2F%23&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:21px;" allowTransparency="true"></iframe></p>

		</div>
]]></description>

			<dc:creator>kojingharang</dc:creator>

			<pubDate>Wed, 28 Jun 2017 09:51:21 GMT</pubDate>



		</item>

		<item>
			<title> 2017 TCO Round2A 500 DistanceZeroAndOne</title>
			<link>https://topcoder.g.hatena.ne.jp/kojingharang/20170521#1495334326</link>

			<description><![CDATA[
		<div class="section">
			<ul>
				<li> 頂点 0〜N-1 の無向連結グラフを作りたい。頂点0〜頂点iの最短距離はdist0[i], 頂点1〜頂点iの最短距離はdist1[i]でないといけない。</li>
				<li> 各辺の距離は 1. 作れるならその一例、作れなければ空を返せ。</li>
				<li> 2≦N≦50</li>
			</ul>
			<ul>
				<li> (TCO出忘れたのであとで)</li>
			</ul>
			<ul>
				<li> 考察</li>
				<li> 連結なので頂点0からの距離が1の頂点は必ずある。</li>
				<li> 同じく頂点0からの距離が M なものがあったら dist0 には 1〜M が含まれる。</li>
			</ul>
			<ul>
				<li> 頂点0 から距離 1 の頂点は頂点0と必ず繋がっている必要がある。(頂点0は1個なので)</li>
				<li> 頂点0 から距離 2 の頂点は頂点0 から距離 1 の頂点のどれかと繋がっている必要がある。</li>
				<li> 頂点1からの距離制約があるので、全部繋げてよいとは限らない。</li>
				<li> 繋げていいやつだけ繋げてどれかと繋がったか判定すればよさそう</li>
				<li> 繋げていいかどうかは、繋げたとき頂点1の距離制約を破らなければよい。</li>
				<li> u, v を繋げるとして、u, v の頂点1 からの距離の差の絶対値が2以上のときに繋げると頂点1からの距離の差が1になってしまうのでだめ</li>
				<li> 元々 1 以下のときはOKなので実際に繋げる</li>
				<li> 最後にできたグラフをWFしてdist0, dist1と矛盾ないかチェック (これやってなくて<a class="keyword" href="https://topcoder.g.hatena.ne.jp/keyword/WA">WA</a>)</li>
			</ul>
			<ul>
				<li> Accepted in practice</li>
			</ul>			<br>

<pre class="syntax-highlight">
<span class="synType">void</span> add(vector&amp;#<span class="synConstant">60</span>;string&amp;#<span class="synConstant">62</span>;&amp;#<span class="synConstant">38</span>; w, <span class="synType">int</span> n0, <span class="synType">int</span> n1) {
	w[n0][n1] = w[n1][n0] = <span class="synConstant">'Y'</span>;
}

<span class="synType">class</span> DistanceZeroAndOne {
	<span class="synStatement">public</span>:
	vector &amp;#<span class="synConstant">60</span>;string&amp;#<span class="synConstant">62</span>; construct(vector &amp;#<span class="synConstant">60</span>;<span class="synType">int</span>&amp;#<span class="synConstant">62</span>; d0, vector &amp;#<span class="synConstant">60</span>;<span class="synType">int</span>&amp;#<span class="synConstant">62</span>; d1) {
		ll N = d0.size();
		<span class="synStatement">if</span>(!(d0[<span class="synConstant">0</span>]==<span class="synConstant">0</span> &amp;#<span class="synConstant">38</span>;&amp;#<span class="synConstant">38</span>; d0[<span class="synConstant">1</span>]==d1[<span class="synConstant">0</span>] &amp;#<span class="synConstant">38</span>;&amp;#<span class="synConstant">38</span>; d1[<span class="synConstant">1</span>]==<span class="synConstant">0</span>)) <span class="synStatement">return</span> {};

		vector&amp;#<span class="synConstant">60</span>;string&amp;#<span class="synConstant">62</span>; g(N, string(N, <span class="synConstant">'N'</span>));
		VVI n0(N), n1(N);
		REP(i, N) n0[d0[i]].PB(i);
		REP(i, N) n1[d1[i]].PB(i);
		RANGE(i, <span class="synConstant">1</span>, N) {
			ll pi = i-<span class="synConstant">1</span>;
			<span class="synStatement">for</span>(<span class="synType">int</span> v2 : n0[i]) {
				<span class="synType">bool</span> any=<span class="synConstant">false</span>;
				<span class="synStatement">for</span>(<span class="synType">int</span> v1 : n0[pi]) {
					<span class="synStatement">if</span>(abs(d1[v1]-d1[v2]) &amp;#<span class="synConstant">60</span>; <span class="synConstant">2</span>) {
						any=<span class="synConstant">true</span>;
						add(g, v1, v2);
					}
				}
				<span class="synStatement">if</span>(!any) <span class="synStatement">return</span> {};
			}
			<span class="synStatement">for</span>(<span class="synType">int</span> v2 : n1[i]) {
				<span class="synType">bool</span> any=<span class="synConstant">false</span>;
				<span class="synStatement">for</span>(<span class="synType">int</span> v1 : n1[pi]) {
					<span class="synStatement">if</span>(abs(d0[v1]-d0[v2]) &amp;#<span class="synConstant">60</span>; <span class="synConstant">2</span>) {
						any=<span class="synConstant">true</span>;
						add(g, v1, v2);
					}
				}
				<span class="synStatement">if</span>(!any) <span class="synStatement">return</span> {};
			}
		}
		VVI w(N, VI(N, <span class="synConstant">1LL</span>&amp;#<span class="synConstant">60</span>;&amp;#<span class="synConstant">60</span>;<span class="synConstant">60</span>));
		REP(i, N) REP(j, N) <span class="synStatement">if</span>(g[i][j]==<span class="synConstant">'Y'</span>) w[i][j]=<span class="synConstant">1</span>;
		REP(i, N) w[i][i]=<span class="synConstant">0</span>;
		REP(k, N) REP(i, N) REP(j, N) w[i][j] = min(w[i][j], w[i][k]+w[k][j]);
		REP(i, N) <span class="synStatement">if</span>(d0[i]!=w[<span class="synConstant">0</span>][i]) <span class="synStatement">return</span> {};
		REP(i, N) <span class="synStatement">if</span>(d1[i]!=w[<span class="synConstant">1</span>][i]) <span class="synStatement">return</span> {};
		<span class="synStatement">return</span> g;
	}
};
</pre>

			<p class="share-button sectionfooter"><a href="http://b.hatena.ne.jp/entry/https://topcoder.g.hatena.ne.jp/kojingharang/%23" class="hatena-bookmark-button" data-hatena-bookmark-title="2017-05-21" data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加"><img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a><script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script><a href="http://twitter.com/share" class="twitter-share-button" data-lang="ja" data-count="none" data-url="https://topcoder.g.hatena.ne.jp/kojingharang/#" data-text="2017-05-21 - kojingharangの日記 (id:kojingharang)">ツイートする</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js" charset="utf-8"></script><iframe src="http://www.facebook.com/plugins/like.php?href=https%3A%2F%2Ftopcoder.g.hatena.ne.jp%2Fkojingharang%2F%23&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:21px;" allowTransparency="true"></iframe></p>

		</div>
]]></description>

			<dc:creator>kojingharang</dc:creator>

			<pubDate>Sun, 21 May 2017 02:38:46 GMT</pubDate>



		</item>

		<item>
			<title> AtCoder Grand Contest 014 D - Black and White Tree</title>
			<link>https://topcoder.g.hatena.ne.jp/kojingharang/20170507#1494118599</link>

			<description><![CDATA[
		<div class="section">
			<ul>
				<li> 木が与えられる。先手は白、後手は黒で塗られてない頂点を順番に塗っていく。塗れなくなったら黒頂点に隣接する頂点を全部黒にする。</li>
				<li> 白が残ってたら先手の勝ち。最適にプレイしたらどっちが勝つか求めよ。</li>
				<li> 2≦頂点数≦10^5</li>
			</ul>
			<ul>
				<li> 葉とその親がどちらも白になったら白が勝つ。</li>
				<li> という状態を作り出すには、葉である子が 2 個以上ある頂点を最初に白に塗ればいい。</li>
				<li> 最初にそういうのがなかったら? う〜む</li>
				<li> 葉である子が 1 個だけの頂点を白に塗ったら、次はその葉を黒にするしかない。</li>
				<li> ? - 親 - 葉 の親と葉を消していくといい?</li>
				<li> それ以外のとこに白を塗ることで勝てることはあるんじゃないかとかいろいろもやっとして終わり</li>
			</ul>
			<ul>
				<li> (あとで)</li>
				<li> 公式解説 → <a href="https://atcoder.jp/img/agc014/editorial.pdf" target="_blank">https://atcoder.jp/img/agc014/editorial.pdf</a></li>
			</ul>
			<ul>
				<li> 帰納法で完全マッチングあり←→後手勝ちが証明できるようだ。</li>
				<li> ? - 親 - 葉 の親と葉を消せるだけ消して、1頂点になった or 葉である子が 2 個以上ある頂点があったら First, なければまた繰り返し、消えなくなったら Second でよかった</li>
			</ul>
			<ul>
				<li> solve1 で remove_if は計算量的にやばいかなと思ったが時間は solve2 と同じくらいだった。</li>
				<li> solve1 は実装だけならできていたかもしれないので、証明がいまいちできない時はそれっぽい実装を進めてしまうというのもありだなぁ特に何回でも試せるコンテストでは。</li>
				<li> solve2 は実際にはノードを消さないちょい賢い方法。あまり思いつく気はしない。</li>
			</ul>
			<ul>
				<li> Accepted in practice</li>
			</ul>
<pre class="syntax-highlight">
ll N;

<span class="synComment">// ノードを実際に消していく版</span>
<span class="synComment">// ? - A - B があったとき A, B を消しまくる。葉である子が 2 個以上ある頂点がでてきたら First</span>
<span class="synComment">// 頂点が 1 個になっても First</span>
<span class="synComment">// なければまた繰り返し</span>
<span class="synComment">// 消えなくなったら Second </span>
string solve1(VVI&amp;#<span class="synConstant">38</span>; g) {
	<span class="synStatement">while</span>(<span class="synConstant">1</span>) {
		ll edges = <span class="synConstant">0</span>;
		REP(i, N) {
			<span class="synType">int</span> cnt=<span class="synConstant">0</span>;
			edges += g[i].size();
			<span class="synStatement">for</span>(<span class="synType">int</span> j : g[i]) {
				<span class="synStatement">if</span>(g[j].size()==<span class="synConstant">1</span>) cnt++;
			}
			<span class="synStatement">if</span>(cnt&amp;#<span class="synConstant">62</span>;=<span class="synConstant">2</span>) {
				<span class="synStatement">return</span> <span class="synConstant">&quot;First&quot;</span>;
			}
		}
		edges/=<span class="synConstant">2</span>;
		<span class="synStatement">if</span>(edges==<span class="synConstant">0</span>) <span class="synStatement">return</span> <span class="synConstant">&quot;First&quot;</span>;

		<span class="synComment">// i - adj - X =... -&amp;#62; X =...</span>
		<span class="synType">bool</span> ch=<span class="synConstant">false</span>;
		REP(i, N) {
			<span class="synStatement">if</span>(g[i].size()==<span class="synConstant">1</span>) {
				<span class="synType">int</span> adj = g[i][<span class="synConstant">0</span>];
				<span class="synStatement">if</span>(g[adj].size()==<span class="synConstant">2</span>) {
					<span class="synType">int</span> X = g[adj][<span class="synConstant">0</span>]==i ? g[adj][<span class="synConstant">1</span>] : g[adj][<span class="synConstant">0</span>];
					{
						<span class="synType">auto</span> en = remove_if(ALL(g[X]), [=](<span class="synType">int</span> a) <span class="synError">{</span> <span class="synStatement">return</span> adj==a; <span class="synError">}</span>);
						g[X].erase(en, g[X].end());
					<span class="synError">}</span>
					g[adj].clear();
					g[i].clear();
					ch=<span class="synConstant">true</span>;
				<span class="synError">}</span>
			<span class="synError">}</span>
		<span class="synError">}</span>
		<span class="synStatement">if</span>(!ch) <span class="synStatement">break</span>;
	<span class="synError">}</span>
	<span class="synStatement">return</span> <span class="synConstant">&quot;Second&quot;</span>;
<span class="synError">}</span>

<span class="synComment">// return: このノード以下で完全マッチの相手を探しているノードの個数</span>
ll dfs(<span class="synType">int</span> u, <span class="synType">int</span> p, VVI&amp;#<span class="synConstant">38</span>; g) <span class="synError">{</span>
	ll x = <span class="synConstant">0</span>;
	<span class="synStatement">for</span>(<span class="synType">int</span> v: g[u]) <span class="synStatement">if</span>(v!=p) x += dfs(v, u, g);
	<span class="synStatement">if</span>(x==<span class="synConstant">0</span>) <span class="synStatement">return</span> <span class="synConstant">1</span>; <span class="synComment">// need to match ... 子が全部マッチしてるので</span>
	<span class="synStatement">if</span>(x==<span class="synConstant">1</span>) <span class="synStatement">return</span> <span class="synConstant">0</span>; <span class="synComment">// matched</span>
	<span class="synStatement">return</span> INF; <span class="synComment">// 余りが確定したので無理</span>
<span class="synError">}</span>

<span class="synComment">// ノードを消さないスマート版</span>
string solve2(VVI&amp;#<span class="synConstant">38</span>; g) <span class="synError">{</span>
	<span class="synComment">// rest==0 ←→ 完全マッチしている</span>
	ll rest = dfs(<span class="synConstant">0</span>, -<span class="synConstant">1</span>, g);
	string ans = rest ? <span class="synConstant">&quot;First&quot;</span> : <span class="synConstant">&quot;Second&quot;</span>;
	<span class="synStatement">return</span> ans;
<span class="synError">}</span>

<span class="synType">int</span> main() <span class="synError">{</span>
	ios::sync_with_stdio(<span class="synConstant">false</span>);
	string s;
	<span class="synStatement">while</span>(cin&amp;#<span class="synConstant">62</span>;&amp;#<span class="synConstant">62</span>;N) <span class="synError">{</span>
		VVI g(N);
		REP(i, N-<span class="synConstant">1</span>) <span class="synError">{</span>
			ll A, B;
			cin&amp;#<span class="synConstant">62</span>;&amp;#<span class="synConstant">62</span>;A&amp;#<span class="synConstant">62</span>;&amp;#<span class="synConstant">62</span>;B;
			A--;B--;
			g[A].PB(B);
			g[B].PB(A);
		<span class="synError">}</span>

<span class="synComment">//		string ans = solve1(g);</span>
		string ans = solve2(g);

		cout&amp;#<span class="synConstant">60</span>;&amp;#<span class="synConstant">60</span>;ans&amp;#<span class="synConstant">60</span>;&amp;#<span class="synConstant">60</span>;endl;
	<span class="synError">}</span>
	
	<span class="synStatement">return</span> <span class="synConstant">0</span>;
<span class="synError">}</span>
</pre>

			<p class="share-button sectionfooter"><a href="http://b.hatena.ne.jp/entry/https://topcoder.g.hatena.ne.jp/kojingharang/%23" class="hatena-bookmark-button" data-hatena-bookmark-title="2017-05-07" data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加"><img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a><script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script><a href="http://twitter.com/share" class="twitter-share-button" data-lang="ja" data-count="none" data-url="https://topcoder.g.hatena.ne.jp/kojingharang/#" data-text="2017-05-07 - kojingharangの日記 (id:kojingharang)">ツイートする</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js" charset="utf-8"></script><iframe src="http://www.facebook.com/plugins/like.php?href=https%3A%2F%2Ftopcoder.g.hatena.ne.jp%2Fkojingharang%2F%23&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:21px;" allowTransparency="true"></iframe></p>

		</div>
]]></description>

			<dc:creator>kojingharang</dc:creator>

			<pubDate>Sun, 07 May 2017 00:56:39 GMT</pubDate>



		</item>

	</channel>
</rss>
