<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>EUYUIL</title> <atom:link href="http://euyuil.com/feed/" rel="self" type="application/rss+xml" /><link>http://euyuil.com</link> <description>折腾使人进步。</description> <lastBuildDate>Wed, 22 Feb 2012 14:16:07 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>解决 Arch Linux 近期更新后无法启动的问题</title><link>http://euyuil.com/3273/arch-linux-unable-to-boot-after-update/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arch-linux-unable-to-boot-after-update</link> <comments>http://euyuil.com/3273/arch-linux-unable-to-boot-after-update/#comments</comments> <pubDate>Wed, 22 Feb 2012 14:16:07 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[Arch Linux]]></category> <category><![CDATA[Linux]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3273</guid> <description><![CDATA[过年的时候一直没开 Arch Linux, 回到学校才更新。更新的过程不太顺利，因为这次 pacman 是大升级，然后内核又有什么升级，所以造成各种冲突。结果我在更新时加入了“强制执行”命令，也就是执行了 pacman -Syuf 这样的命令，重启后就没法再启动了。提示信息： Unable to find root device /dev/... 后来还是去 Arch Linux 论坛上找，才找到解决方案。大概的思路，是要用 Arch Linux 安装光盘启动，然后 chroot 到硬盘上的系统，再更新 udev, mkinitcpio 之类的东西，才能再次启动。 首先从 Arch Linux 的官方网站上下载 Arch Linux 镜像，我选择的不是网络安装版，不知道网络安装版能不能用，没试过。由于是在学校机房下载的，我选择了教育网镜像。 我是打算用 U 盘启动的，学校机房的电脑又是 Windows, 所以就下载了一个 Cygwin, 使用 dd 把镜像刷到 U 盘里： ~ # dd if=archlinux.iso of=/dev/sdb 如果不能确定 U 盘是哪个设备，可以用如下命令查看有什么分区（似乎 fdisk -l [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">过年的时候一直没开 Arch Linux, 回到学校才更新。更新的过程不太顺利，因为这次 <span
style="font-family: 'courier new', courier;" >pacman</span> 是大升级，然后内核又有什么升级，所以造成各种冲突。结果我在更新时加入了“强制执行”命令，也就是执行了 <span
style="font-family: 'courier new', courier;" >pacman -Syuf</span> 这样的命令，重启后就没法再启动了。提示信息：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;">Unable to find root device /dev/...</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">后来还是去 Arch Linux 论坛上找，才找到解决方案。大概的思路，是要用 Arch Linux 安装光盘启动，然后 <span
style="font-family: 'courier new', courier;" >chroot</span> 到硬盘上的系统，再更新 <span
style="font-family: 'courier new', courier;" >udev</span>, <span
style="font-family: 'courier new', courier;" >mkinitcpio</span> 之类的东西，才能再次启动。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3273" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">首先从 Arch Linux 的官方网站上<a
title="Arch Linux Downloads"  href="http://www.archlinux.org/download/"  target="_blank" >下载 Arch Linux 镜像</a>，我选择的不是网络安装版，不知道网络安装版能不能用，没试过。由于是在学校机房下载的，我选择了教育网镜像。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">我是打算用 U 盘启动的，学校机房的电脑又是 Windows, 所以就下载了一个 Cygwin, 使用 <span
style="font-family: 'courier new', courier;" >dd</span> 把镜像刷到 U 盘里：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >~ #</span> dd if=archlinux.iso of=/dev/sdb</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">如果不能确定 U 盘是哪个设备，可以用如下命令查看有什么分区（似乎 <span
style="font-family: 'courier new', courier;" >fdisk -l</span> 在 Cygwin 下没用）：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >~ #</span> cat /proc/partitions</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">在那台电脑上启动 U 盘的 Arch Linux 系统，然后用 <span
style="font-family: 'courier new', courier;" >fdisk -l</span> 查到你原来装有 Arch Linux 硬盘是哪个设备（本文假设是 <span
style="font-family: 'courier new', courier;" >/dev/sda1</span>）：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >/ #</span> mkdir /mnt/arch
<span style="color: #888888;" >/ #</span> mount /dev/sda1 /mnt/arch
<span style="color: #888888;" >/ #</span> cd /mnt/arch
<span style="color: #888888;" >/mnt/arch #</span> mount -t proc proc proc/
<span style="color: #888888;" >/mnt/arch #</span> mount -t sysfs sys sys/
<span style="color: #888888;" >/mnt/arch #</span> mount -o bind /dev dev/</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">如果你的启动分区不是独立分区，那么下面这个步骤不用做。我的启动分区是 <span
style="font-family: 'courier new', courier;" >/dev/sda2</span>, 要将其挂载到 <span
style="font-family: 'courier new', courier;" >boot/</span> 上：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >/mnt/arch #</span> mount /dev/sda2 boot/</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">然后开始 <span
style="font-family: 'courier new', courier;" >chroot</span> 到当前目录（<span
style="font-family: 'courier new', courier;" >/mnt/arch</span>）：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >/mnt/arch #</span> chroot . /bin/bash
<span style="color: #888888;" >/ #</span> source /etc/profile</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">之后的步骤需要连接到网络。我是直接连在路由器上，就开 DHCP 客户端就可以了，其它的上网方式需要其它的设置。</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >/ #</span> dhcpcd eth0</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">然后，最重要的步骤来了，重装 <span
style="font-family: 'courier new', courier;" >udev</span> 然后重建镜像：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >/ #</span> pacman -Syy
<span style="color: #888888;" >/ #</span> pacman -Syu
<span style="color: #888888;" >/ #</span> pacman -S udev
<span style="color: #888888;" >/ #</span> pacman -S mkinitcpio
<span style="color: #888888;" >/ #</span> mkinitcpio -p linux
<span style="color: #888888;" >/ #</span> reboot</pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">重启之后一般可以看到久违的的画面了。这个时候我是重装了所有的软件包，这样一些其它的错误也修复了：</p><pre  style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><span style="color: #888888;" >/ #</span> comm -23 &lt;(pacman -Qeq) &lt;(pacman -Qmq) | pacman -S -
<span style="color: #888888;" >/ #</span> comm -23 &lt;(pacman -Qdq) &lt;(pacman -Qmq) | pacman -S --asdeps -</pre><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3273/arch-linux-unable-to-boot-after-update/" >http://euyuil.com/3273/arch-linux-unable-to-boot-after-update/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3273/arch-linux-unable-to-boot-after-update/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Codeforces 150B Quantity of Strings</title><link>http://euyuil.com/3266/codeforces-150b-quantity-of-strings/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=codeforces-150b-quantity-of-strings</link> <comments>http://euyuil.com/3266/codeforces-150b-quantity-of-strings/#comments</comments> <pubDate>Sun, 19 Feb 2012 11:44:44 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[Codeforces]]></category> <category><![CDATA[排列组合]]></category> <category><![CDATA[题解]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3266</guid> <description><![CDATA[这道题是 Codeforces Round #107 (Div. 2) 中的 D 题。其题意是，给出 n, m, k 三个整数，问在字母表有 m 个元素的、长度为 n 的字符串中，存在多少个这样的字符串，其所有长度为 k 的子串是回文串。 一开始我理解错题意了，我当时以为是只要那个串含有回文子串，那么就把它算进去。其实我感觉还是挺傻的，因为长度为 1 的串也是回文串啊，那这样岂不是所有的都要算进去了？ 这样的话问题就简单多了。首先考虑当 k > n 时，由于此时长度为 n 的串中，长度为 k 的子串是不存在的。可以这么说，这个子串的集合是空集。那么，我说 ∅ 中的任何一个元素，都是回文串，这是没有问题的吧。如果你觉得有问题，那你找一个不是回文串的元素出来看看呀？ （以下段落的存在是为了说明“空集中的任何一个元素都是回文串”。） 其实上面那种情况是一个逻辑问题，有的时候用代码来解释一些现象还是比较方便的。打个比方，0 的阶乘大家都知道应该是 1 吧，为什么是 1 呢？看代码： int frac(int n) { int r = 1; for (int i = 1; i &#60;= [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这道题是 <a
href="http://euyuil.com/3254/codeforces-round-107-div-2/"  title="Codeforces Round #107 (Div. 2)"  target="_blank" >Codeforces Round #107 (Div. 2)</a> 中的 D 题。其题意是，给出 n, m, k 三个整数，问在字母表有 m 个元素的、长度为 n 的字符串中，存在多少个这样的字符串，其所有长度为 k 的子串是回文串。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">一开始我理解错题意了，我当时以为是只要那个串含有回文子串，那么就把它算进去。其实我感觉还是挺傻的，因为长度为 1 的串也是回文串啊，那这样岂不是所有的都要算进去了？</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3266" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这样的话问题就简单多了。首先考虑当 k > n 时，由于此时长度为 n 的串中，长度为 k 的子串是不存在的。可以这么说，这个子串的集合是空集。那么，我说 <strong>∅ 中的任何一个元素，都是回文串</strong>，这是没有问题的吧。如果你觉得有问题，那你找一个不是回文串的元素出来看看呀？</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
style="color:gray;" >（以下段落的存在是为了说明“空集中的任何一个元素都是回文串”。）</span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">其实上面那种情况是一个逻辑问题，有的时候用代码来解释一些现象还是比较方便的。打个比方，0 的阶乘大家都知道应该是 1 吧，为什么是 1 呢？看代码：</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>int frac(int n)
{
	int r = 1;
	for (int i = 1; i &lt;= n; ++i)
		r *= i;
	return r;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这是计算阶乘的代码，如果将 0 传给参数 n, 那么返回的值应该是 1.</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">好，那么如果有一个函数，可以判断集合 s 中，是不是每个元素都是回文串。那么代码应该这么写：</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>bool is_palindrome(const string &amp;n)
{
	return whether_n_is_a_palindrome_string;
}
bool are_all_palindromes(const set&lt;string&gt; &amp;s)
{
	set&lt;string&gt;::iterator it;
	for (it = s.begin(); it != s.end(); ++it)
		if (!is_palindrome(*it))
			return false;
	return true;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">如果给 are_all_palindromes 的参数 s 传入的是空集，那么，上面的函数会返回 true. 所以，k > n 的时候，任何一个长度为 n 的串的长度为 k 的子串都是回文串。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
style="color:gray;" >（说明完毕。）</span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">其它情况，当 k < n 的时候：如果 k 是偶数，那么那些所有元素都是一样的串才能符合要求；如果 k 是奇数但不是 1, 那么那些只有两种元素的串才能符合要求；如果 k 是 1 那么所有的串都符合要求。所以代码如下：</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;iostream&gt;
using namespace std;
inline int power(int a, int n)
{
	long long result = 1;
	while (n--)
		result = (result * a) % 1000000007;
	return result;
}
int main()
{
	int n, m, k;
	cin &gt;&gt; n &gt;&gt; m &gt;&gt; k;
	if (k == 1 || k &gt; n)
		cout &lt;&lt; power(m, n) &lt;&lt; endl;
	else if (k == n)
		cout &lt;&lt; power(m, (n + 1) &gt;&gt; 1) &lt;&lt; endl;
	else if (k &amp; 1) // k is odd.
		cout &lt;&lt; m * m &lt;&lt; endl;
	else // k is even.
		cout &lt;&lt; m &lt;&lt; endl;
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3266/codeforces-150b-quantity-of-strings/" >http://euyuil.com/3266/codeforces-150b-quantity-of-strings/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3266/codeforces-150b-quantity-of-strings/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>TopCoder Single Round Match 533</title><link>http://euyuil.com/3258/topcoder-single-round-match-533/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=topcoder-single-round-match-533</link> <comments>http://euyuil.com/3258/topcoder-single-round-match-533/#comments</comments> <pubDate>Sun, 19 Feb 2012 08:23:19 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[TopCoder]]></category> <category><![CDATA[字符串处理]]></category> <category><![CDATA[水题]]></category> <category><![CDATA[递归]]></category> <category><![CDATA[题解]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3258</guid> <description><![CDATA[这个比赛是在今天凌晨 1:05 开始的，感觉以后做这种还是需要先休息一下。 250 分的题，题意是，皮卡丘只会说三个音节：“pi”、“ka”、“chu”；给出一个只有小写字母的字符串，判断皮卡丘能不能说出这样的话。比如，“pikachu”、“pikapika”之类的要输出“YES”，反之输出“NO”。 我的办法比较笨，都是逐个字母来判断的。但是我感觉这种方法比较快，是 O(n) 的算法。在 Challenge 的时候看到一种方法，每次判断开头几个字母是不是“pi”、“ka”、“chu”，如果不是就直接返回“NO”了，如果是的话，就删除前面几个字母。但是这种方法似乎没法通过系统测试，不过在 Challenge 阶段这样的题解也没人敢动，所以这样错的原因可能是效率比较低。 #include &#60;string&#62; using namespace std; class PikachuEasy { public: string check(string word) { int i; for (i = 0; i &#60; word.length(); ++i) { if (word[i] == 'p') { if (++i &#62;= word.length()) return &#34;NO&#34;; if (word[i] != 'i') return &#34;NO&#34;; } else [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这个比赛是在今天凌晨 1:05 开始的，感觉以后做这种还是需要先休息一下。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">250 分的题，题意是，皮卡丘只会说三个音节：“<span
style="font-family: 'courier new', courier;" >pi</span>”、“<span
style="font-family: 'courier new', courier;" >ka</span>”、“<span
style="font-family: 'courier new', courier;" >chu</span>”；给出一个只有小写字母的字符串，判断皮卡丘能不能说出这样的话。比如，“<span
style="font-family: 'courier new', courier;" >pikachu</span>”、“<span
style="font-family: 'courier new', courier;" >pikapika</span>”之类的要输出“<span
style="font-family: 'courier new', courier;" >YES</span>”，反之输出“<span
style="font-family: 'courier new', courier;" >NO</span>”。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">我的办法比较笨，都是逐个字母来判断的。但是我感觉这种方法比较快，是 <span
style="font-family: 'times new roman', times;" >O(<em>n</em>)</span> 的算法。在 Challenge 的时候看到一种方法，每次判断开头几个字母是不是“<span
style="font-family: 'courier new', courier;" >pi</span>”、“<span
style="font-family: 'courier new', courier;" >ka</span>”、“<span
style="font-family: 'courier new', courier;" >chu</span>”，如果不是就直接返回“<span
style="font-family: 'courier new', courier;" >NO</span>”了，如果是的话，就删除前面几个字母。但是这种方法似乎没法通过系统测试，不过在 Challenge 阶段这样的题解也没人敢动，所以这样错的原因可能是效率比较低。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3258" ></span></p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;string&gt;
using namespace std;
class PikachuEasy
{
public:
	string check(string word)
	{
		int i;
		for (i = 0; i &lt; word.length(); ++i)
		{
			if (word[i] == 'p')
			{
				if (++i &gt;= word.length())
					return &quot;NO&quot;;
				if (word[i] != 'i')
					return &quot;NO&quot;;
			}
			else if (word[i] == 'k')
			{
				if (++i &gt;= word.length())
					return &quot;NO&quot;;
				if (word[i] != 'a')
					return &quot;NO&quot;;
			}
			else if (word[i] == 'c')
			{
				if (++i &gt;= word.length())
					return &quot;NO&quot;;
				if (word[i] != 'h')
					return &quot;NO&quot;;
				if (++i &gt;= word.length())
					return &quot;NO&quot;;
				if (word[i] != 'u')
					return &quot;NO&quot;;
			}
			else
				return &quot;NO&quot;;
		}
		return &quot;YES&quot;;
	}
};</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">500 分的题目，题意是，有 <em><span
style="font-family: 'times new roman', times;" >n</span></em> 个数字，每次可以删除其中“不是首位的”数字，然后获得那个被删除数字左右两个数字之乘积的能量。这些数字都是正的。数据范围是 <span
style="font-family: 'times new roman', times;" >3 ≤ <em>n</em> ≤ 10</span>, 那这样的话即使用穷举也是最多 <span
style="font-family: 'times new roman', times;" >8! = 40320</span>, 这就无压力了。</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;vector&gt;
#include &lt;algorithm&gt;
using namespace std;
class CasketOfStarEasy
{
public:
	int maxEnergy(vector&lt;int&gt; weight)
	{
		return maxEnergyRecursive(weight);
	}
	int maxEnergyRecursive(const vector&lt;int&gt; &amp;weight)
	{
		if (weight.size() == 3)
			return weight[0] * weight[2];
		int result, max_result = 0;
		for (int i = 1; i &lt; weight.size() - 1; ++i)
		{
			vector&lt;int&gt; clone = weight;
			clone.erase(clone.begin() + i);
			result = maxEnergy(clone) + weight[i - 1] * weight[i + 1];
			max_result = max(max_result, result);
		}
		return max_result;
	}
};</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">1000 分的题目，不会做。和室友讨论了将近 40 分钟，没有什么结果。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">然后 Challenge 阶段，居然意外地搞了两份代码。今天早上起床的时候，发现 Rating 涨了，终于变成了绿人……<div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3258/topcoder-single-round-match-533/" >http://euyuil.com/3258/topcoder-single-round-match-533/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3258/topcoder-single-round-match-533/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Codeforces Round #107 (Div. 2)</title><link>http://euyuil.com/3254/codeforces-round-107-div-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=codeforces-round-107-div-2</link> <comments>http://euyuil.com/3254/codeforces-round-107-div-2/#comments</comments> <pubDate>Sat, 18 Feb 2012 10:14:14 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[Codeforces]]></category> <category><![CDATA[字符串处理]]></category> <category><![CDATA[数论]]></category> <category><![CDATA[水题]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3254</guid> <description><![CDATA[几个月不参加 Codeforces 的比赛了，没有紧张的气氛，做得有点没感觉。前两题水过，第三题想复杂了，第四题当时没有想法，最后一题没心情看。比赛 URL: http://codeforces.com/contest/151 . A 题 151A Soft Drinking 的背景是几个好朋友在一起喝饮料。其问题的实质是这样的：要制造一种物品，需要不同数量的不同原料；给出各种原料的数量和每件物品需要每种原料各多少，然后求最多能制造多少个这种物品。 #include &#60;climits&#62; #include &#60;iostream&#62; #include &#60;algorithm&#62; using namespace std; int main() { int n, k, l, c, d, p, nl, np, r = INT_MAX; cin &#62;&#62; n &#62;&#62; k &#62;&#62; l &#62;&#62; c &#62;&#62; d &#62;&#62; p &#62;&#62; nl &#62;&#62; np; r = [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">几个月不参加 <a
href="http://codeforces.com/"  title="Codeforces"  target="_blank" ><em>Codeforces</em></a> 的比赛了，没有紧张的气氛，做得有点没感觉。前两题水过，第三题想复杂了，第四题当时没有想法，最后一题没心情看。比赛 URL: <a
href="http://codeforces.com/contest/151"  title="Codeforces Round #107 (Div. 2)"  target="_blank" >http://codeforces.com/contest/151</a> .</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">A 题 <strong>151A Soft Drinking</strong> 的背景是几个好朋友在一起喝饮料。其问题的实质是这样的：要制造一种物品，需要不同数量的不同原料；给出各种原料的数量和每件物品需要每种原料各多少，然后求最多能制造多少个这种物品。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3254" ></span></p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;climits&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;
using namespace std;
int main()
{
	int n, k, l, c, d, p, nl, np, r = INT_MAX;
	cin &gt;&gt; n &gt;&gt; k &gt;&gt; l &gt;&gt; c &gt;&gt; d &gt;&gt; p &gt;&gt; nl &gt;&gt; np;
	r = min(r, k * l / nl);
	r = min(r, c * d);
	r = min(r, p / np);
	cout &lt;&lt; r / n &lt;&lt; endl;
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">B 题 <strong>151B Phone Numbers</strong> 的背景是几个好朋友的电话本。某市的电话是 <span
style="font-family: 'times new roman', times;" >6</span> 位数，都是以 <span
style="font-family: 'courier new', courier;" >22-22-22</span> 这样的形式给出。有三种类型的电话，一种是计程车电话，其特点是电话每个数字都相同；一种是披萨外卖电话，其特点是几个数字是递减的；其余的是妹子的电话。最后问，拥有计程车的电话、披萨外卖电话和妹子的电话最多的人分别是谁。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">后来看到别人的博客，里面说 B 题如果没有人有某种类型的电话，那么这个时候要把所有人的名字输出。但是我的代码里没有考虑这种情况，似乎这样也 AC 了。</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;cctype&gt;
#include &lt;iostream&gt;
using namespace std;
inline bool is_taxi(const string &amp;str)
{
	char first = str[0];
	for (int i = 0; i &lt; str.size(); ++i)
		if (isdigit(str[i]))
			if (str[i] != first)
				return false;
	return true;
}
inline bool is_pizza(const string &amp;str)
{
	char previous = str[0];
	for (int i = 1; i &lt; str.size(); ++i)
		if (isdigit(str[i]))
			if (str[i] &gt;= previous)
				return false;
			else
				previous = str[i];
	return true;
}
inline int phone_type(const string &amp;str)
{
	if (is_taxi(str))
		return 0;
	if (is_pizza(str))
		return 1;
	return 2;
}
const char OUTPUT_FORMAT[3][128] = {
	&quot;If you want to call a taxi, you should call: &quot;,
	&quot;If you want to order a pizza, you should call: &quot;,
	&quot;If you want to go to a cafe with a wonderful girl, you should call: &quot;
};
int best_count[3] = {0};
vector&lt;string&gt; best_names[3];
int main()
{
	// freopen(&quot;input.txt&quot;, &quot;r&quot;, stdin);
	int n; cin &gt;&gt; n;
	while (n--)
	{
		int s, cnt[3] = {0};
		string name, phone;
		cin &gt;&gt; s &gt;&gt; name;
		while (s--)
		{
			cin &gt;&gt; phone;
			++cnt[phone_type(phone)];
		}
		for (int i = 0; i &lt; 3; ++i)
		{
			if (cnt[i] &gt; best_count[i])
			{
				best_count[i] = cnt[i];
				best_names[i].clear();
				best_names[i].push_back(name);
			}
			else if (cnt[i] == best_count[i])
			{
				best_names[i].push_back(name);
			}
		}
	}
	for (int i = 0; i &lt; 3; ++i)
	{
		cout &lt;&lt; OUTPUT_FORMAT[i];
		if (!best_names[i].empty())
		{
			cout &lt;&lt; best_names[i][0];
			for (int j = 1; j &lt; best_names[i].size(); ++j)
				cout &lt;&lt; &quot;, &quot; &lt;&lt; best_names[i][j];
		}
		cout &lt;&lt; &quot;.&quot; &lt;&lt; endl;
	}
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">C 题 <strong>150A Win or Freeze</strong> 说的是两个人玩游戏，一开始 <span
style="font-family: 'times new roman', times;" >1</span> 号玩家面临一个数 <em><span
style="font-family: 'times new roman', times;" >p</span></em>, 如果他能写出 <em><span
style="font-family: 'times new roman', times;" >p</span></em> 的一个非平凡因数 <em><span
style="font-family: 'times new roman', times;" >q</span></em>, 就可以轮到玩家 <span
style="font-family: 'times new roman', times;" >2</span>, 让他写出 <em><span
style="font-family: 'times new roman', times;" >q</span></em> 的非平凡因数 <em><span
style="font-family: 'times new roman', times;" >r</span></em>, &#8230; 直到某个玩家不能写为止，然后那个不能继续写数的玩家获胜。输入数据给出数 <em><span
style="font-family: 'times new roman', times;" >p</span></em>, 问哪个玩家能获胜；如果 <span
style="font-family: 'times new roman', times;" >1</span> 号玩家获胜，第二行要输出 <span
style="font-family: 'times new roman', times;" >1</span> 号玩家应该写的数字是什么。如果 <span
style="font-family: 'times new roman', times;" >1</span> 号玩家一开始就赢了，那么就在第二行输出 <span
style="font-family: 'times new roman', times;" >0</span>.</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这题一开始我的想法是，如果一个数是质数或者 <span
style="font-family: 'times new roman', times;" >1</span>, 那么 <span
style="font-family: 'times new roman', times;" >1</span> 号玩家就没法写数了，他就直接赢了。如果开始的数是两个质数的乘积，那么 <span
style="font-family: 'times new roman', times;" >1</span> 号玩家只能写其中一个质因数，那 <span
style="font-family: 'times new roman', times;" >2</span> 号玩家就赢了。如果是 <span
style="font-family: 'times new roman', times;" >&gt; 2</span> 个质因数，那 <span
style="font-family: 'times new roman', times;" >1</span> 号玩家可以找出其中两个质因数，相乘，写出那个数给 <span
style="font-family: 'times new roman', times;" >2</span> 号玩家，这样 <span
style="font-family: 'times new roman', times;" >2</span> 号玩家只能写一个质数，然后 <span
style="font-family: 'times new roman', times;" >1</span> 号就赢了。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这题的数据范围比较大，当时我居然想到用 Miller-Rabin 算法。开始的时候 pretest 7 总是过不了，赛后发现那个数据是 <span
style="font-family: 'courier new', courier;" >445538663413</span>, 是一个比较大的质数，似乎让 Miller-Rabin 判断了几次都没判断出来，比赛时我也没发现，后来用一些小 trick 也算解决了这个问题（只是不能一开始就判断出是不是素数，浪费了一些时间罢了，算法看起来似乎还是对的）。后来赛后的 test 28 把我这题 WA 了，数据是 <span
style="font-family: 'courier new', courier;" >9999926826034</span>, 这是 <span
style="font-family: 'courier new', courier;" >2</span> 和一个 <span
style="font-family: 'courier new', courier;" >4999963413017</span> 的乘积，似乎后者是质数，然后 Miller-Rabin 也把它判错了。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">其实这题根本不用这么复杂的方法，直接试除就可以了，管你质数不质数的，找到两个约数，发现原数除完它们后不是 <span
style="font-family: 'times new roman', times;" >1</span>, 玩家 <span
style="font-family: 'times new roman', times;" >1</span> 就赢了；反之若是 <span
style="font-family: 'times new roman', times;" >1</span> 就玩家 <span
style="font-family: 'times new roman', times;" >2</span> 赢。如果找到 [latex]\sqrt{p}[/latex] 还是没有约数，那 <em><span
style="font-family: 'times new roman', times;" >p</span></em> 就是质数了，还是玩家 <span
style="font-family: 'times new roman', times;" >1</span> 赢。</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;iostream&gt;
using namespace std;
typedef long long ll;
int main()
{
	int cnt = 0;
	ll p, d[2];
	cin &gt;&gt; p;
	for (ll i = 2; i * i &lt;= p; ++i)
	{
		while (p % i == 0)
		{
			p /= i;
			d[cnt] = i;
			if (++cnt &gt;= 2)
				goto out;
		}
	}
out:
	if (cnt == 0)
		cout &lt;&lt; 1 &lt;&lt; endl &lt;&lt; 0 &lt;&lt; endl;
	else if (p == 1 || cnt == 1)
		cout &lt;&lt; 2 &lt;&lt; endl;
	else
		cout &lt;&lt; 1 &lt;&lt; endl &lt;&lt; d[0] * d[1] &lt;&lt; endl;
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><del
datetime="2012-02-19T11:45:07+00:00" >D 和 </del>E 到时候再研究一下吧，要加油啊。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
style="color:red;" >2012 年 2 月 19 日更新</span>：<a
href="http://euyuil.com/3266/codeforces-150b-quantity-of-strings/"  title="Codeforces 150B Quantity of Strings"  target="_blank" >D 题 <strong>150B Quantity of Strings</strong> 的题解请点击这里</a>。<div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3254/codeforces-round-107-div-2/" >http://euyuil.com/3254/codeforces-round-107-div-2/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3254/codeforces-round-107-div-2/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>ACM/ICPC 2010 杭州现场赛 To Be a Dream Architect 题解</title><link>http://euyuil.com/3250/acm-icpc-2010-hangzhou-to-be-a-dream-architect/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=acm-icpc-2010-hangzhou-to-be-a-dream-architect</link> <comments>http://euyuil.com/3250/acm-icpc-2010-hangzhou-to-be-a-dream-architect/#comments</comments> <pubDate>Wed, 15 Feb 2012 13:17:18 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[区域赛]]></category> <category><![CDATA[现场赛]]></category> <category><![CDATA[空间几何]]></category> <category><![CDATA[题解]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3250</guid> <description><![CDATA[这道题的题意是给出一个 N × N 的正方体，这个正方体是由 1 × 1 的小正方体垒成的。然后，输入数据会给出若干个命令，这些命令都表示一条平行于某坐标轴的直线，命令的效果是让这个直线上的所有方块消失掉。最后，问消失了多少小方块。 似乎这道题原题标题犯了个小小的语法错误…… 关于这道题的解法，Greenmoon55 说，可以用 vector + sort + unique 系列的方法解决这个问题，还提到 set 可能会超时超内存[GRN'11]。我想原因是插入删除过程其实是 O(logn) 的，并且使用动态内存分配频繁，各种冗余数据比较多吧。这种方法的时间复杂度是 O(n2logn). 我的解法是另一种，我使用一个数组 planes[3][N][N], 记录输入的每一条直线。在每执行一条直线的命令的时候，判断某一个方块是否已经被其它直线去掉了。所以这就降了一维，复杂度是 O(n2). 但是现场赛时，我可能会采取 Greenmoon55 的做法。 源代码 #include &#60;cstdio&#62; #include &#60;cstring&#62; using namespace std; const int N = 1001; bool planes[3][N][N]; int n, m; inline bool is_coord_valid(int x, int y) { [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这道题的题意是给出一个 <em><span
style="font-family: 'times new roman', times;" >N</span></em> × <em><span
style="font-family: 'times new roman', times;" >N</span></em> 的正方体，这个正方体是由 <span
style="font-family: 'times new roman', times;" >1</span> × <span
style="font-family: 'times new roman', times;" >1</span> 的小正方体垒成的。然后，输入数据会给出若干个命令，这些命令都表示一条平行于某坐标轴的直线，命令的效果是让这个直线上的所有方块消失掉。最后，问消失了多少小方块。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">似乎这道题原题标题犯了个小小的语法错误……</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3250" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">关于这道题的解法，Greenmoon55 说，可以用 <span
style="font-family: 'courier new', courier;" >vector</span> + <span
style="font-family: 'courier new', courier;" >sort</span> + <span
style="font-family: 'courier new', courier;" >unique</span> 系列的方法解决这个问题，还提到 <span
style="font-family: 'courier new', courier;" >set</span> 可能会超时超内存<sup><a
title="HDU3682 To Be an Dream Architect"  href="#grn11" >[GRN'11]</a></sup>。我想原因是插入删除过程其实是 <span
style="font-family: 'times new roman', times;" >O(log<em>n</em>)</span> 的，并且使用动态内存分配频繁，各种冗余数据比较多吧。这种方法的时间复杂度是 <span
style="font-family: 'times new roman', times;" >O(<em>n</em><sup>2</sup>log<em>n</em>)</span>.</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">我的解法是另一种，我使用一个数组 <span
style="font-family: 'courier new', courier;" >planes[3][N][N]</span>, 记录输入的每一条直线。在每执行一条直线的命令的时候，判断某一个方块是否已经被其它直线去掉了。所以这就降了一维，复杂度是 <span
style="font-family: 'times new roman', times;" >O(<em>n</em><sup>2</sup>)</span>. 但是现场赛时，我可能会采取 Greenmoon55 的做法。</p><h2>源代码</h2><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;cstdio&gt;
#include &lt;cstring&gt;
using namespace std;
const int N = 1001;
bool planes[3][N][N];
int n, m;
inline bool is_coord_valid(int x, int y)
{
	if (x &gt;= 1 &amp;&amp; x &lt;= n &amp;&amp; y &gt;= 0 &amp;&amp; y &lt;= n)
		return true;
	return false;
}
inline int count_cubes(int i0, int x, int y)
{
	int i1 = (i0 + 1) % 3, i2 = (i0 + 2) % 3;
	if (planes[i0][x][y])
		return 0; // Already counted.
	planes[i0][x][y] = true;
	int result = 0;
	for (int z = 1; z &lt;= n; ++z)
		if (!planes[i1][y][z] &amp;&amp; !planes[i2][z][x])
			++result;
	return result;
}
int main()
{
	int T, x, y, r; char a, b, buf[32];
	scanf(&quot;%d&quot;, &amp;T);
	while (T--)
	{
		scanf(&quot;%d %d&quot;, &amp;n, &amp;m); r = 0;
		memset(planes, false, sizeof planes);
		for (int i = 0; i &lt; m; ++i)
		{
			gets(buf); // Skip EOLN.
			scanf(&quot;%c=%d,%c=%d&quot;, &amp;a, &amp;x, &amp;b, &amp;y);
			if (a == 'X' &amp;&amp; b == 'Y') r += count_cubes(0, x, y);
			else if (a == 'Y' &amp;&amp; b == 'X') r += count_cubes(0, y, x);
			else if (a == 'Y' &amp;&amp; b == 'Z') r += count_cubes(1, x, y);
			else if (a == 'Z' &amp;&amp; b == 'Y') r += count_cubes(1, y, x);
			else if (a == 'Z' &amp;&amp; b == 'X') r += count_cubes(2, x, y);
			else if (a == 'X' &amp;&amp; b == 'Z') r += count_cubes(2, y, x);
		}
		printf(&quot;%d\n&quot;, r);
	}
	return 0;
}</code></pre><h2>参考</h2><ul><li
id="grn11" ><em>[GRN'11]</em> <a
title="HDU3682 To Be an Dream Architect"  href="http://greenmoon55.com/hdu3682-to-be-an-dream-architect/"  target="_blank" >Greenmoon55:《HDU3682 To Be an Dream Architect》</a></li></ul><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3250/acm-icpc-2010-hangzhou-to-be-a-dream-architect/" >http://euyuil.com/3250/acm-icpc-2010-hangzhou-to-be-a-dream-architect/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3250/acm-icpc-2010-hangzhou-to-be-a-dream-architect/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>ACM/ICPC 2010 杭州现场赛 National Day Parade 题解</title><link>http://euyuil.com/3245/acm-icpc-2010-hangzhou-national-day-parade/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=acm-icpc-2010-hangzhou-national-day-parade</link> <comments>http://euyuil.com/3245/acm-icpc-2010-hangzhou-national-day-parade/#comments</comments> <pubDate>Wed, 15 Feb 2012 06:44:19 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[区域赛]]></category> <category><![CDATA[水题]]></category> <category><![CDATA[现场赛]]></category> <category><![CDATA[题解]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3245</guid> <description><![CDATA[这是在 Greenmoon55&#8242;s Blog 挖掘出来的水题一则。果断凑数。 思路是把每行的学生的列坐标分别排序，枚举左边一列的列号即可。 代码如下： #include &#60;cmath&#62; #include &#60;cstdio&#62; #include &#60;climits&#62; #include &#60;cstring&#62; #include &#60;iostream&#62; #include &#60;algorithm&#62; using namespace std; const int N = 222; int i2j[N][N], cnt[N], n, m, n2; int main() { // freopen(&#34;input.txt&#34;, &#34;r&#34;, stdin); while (cin &#62;&#62; n &#62;&#62; m) { if (n == 0 &#38;&#38; m == 0) break; [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这是<a
href="http://greenmoon55.com/hdu3687-national-day-parade/"  title="HDU3687 National Day Parade"  target="_blank" >在 Greenmoon55&#8242;s Blog 挖掘出来的水题一则</a>。果断凑数。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">思路是把每行的学生的列坐标分别排序，枚举左边一列的列号即可。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3245" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">代码如下：</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;cmath&gt;
#include &lt;cstdio&gt;
#include &lt;climits&gt;
#include &lt;cstring&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;
using namespace std;
const int N = 222;
int i2j[N][N], cnt[N], n, m, n2;
int main()
{
	// freopen(&quot;input.txt&quot;, &quot;r&quot;, stdin);
	while (cin &gt;&gt; n &gt;&gt; m)
	{
		if (n == 0 &amp;&amp; m == 0)
			break;
		memset(cnt, 0, sizeof cnt);
		n2 = n * n;
		for (int i = 0; i &lt; n2; ++i)
		{
			int k, a; cin &gt;&gt; k; --k;
			cin &gt;&gt; a; --a; i2j[k][cnt[k]++] = a;
		}
		for (int i = 0; i &lt; n; ++i)
			sort(i2j[i], i2j[i] + n);
		int rmost = m - n, sum, result = INT_MAX;
		for (int i = 0; i &lt;= rmost; ++i)
		{
			sum = 0;
			for (int j = 0; j &lt; n; ++j)
				for (int k = 0; k &lt; n; ++k)
					sum += abs(i2j[j][k] - (i + k));
			result = min(result, sum);
		}
		cout &lt;&lt; result &lt;&lt; endl;
	}
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3245/acm-icpc-2010-hangzhou-national-day-parade/" >http://euyuil.com/3245/acm-icpc-2010-hangzhou-national-day-parade/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3245/acm-icpc-2010-hangzhou-national-day-parade/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>ACM/ICPC 2009 合肥现场赛 Laser in Cuboids 题解</title><link>http://euyuil.com/3241/acm-icpc-2009-hefei-laser-in-cuboids/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=acm-icpc-2009-hefei-laser-in-cuboids</link> <comments>http://euyuil.com/3241/acm-icpc-2009-hefei-laser-in-cuboids/#comments</comments> <pubDate>Wed, 15 Feb 2012 05:57:54 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[区域赛]]></category> <category><![CDATA[数论]]></category> <category><![CDATA[最大公约数]]></category> <category><![CDATA[现场赛]]></category> <category><![CDATA[空间几何]]></category> <category><![CDATA[题解]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3241</guid> <description><![CDATA[这道题的题意是，问一个由单位正方体垒成的 A × B × C 的长方体的体对角线穿过了这个长方体中的几个单位正方体。如果对角线与正方体擦肩而过的话不算穿过。 怎么说呢，这道题纠结了几天，网上没有题解，只有模糊地提到容斥原理。在昨晚出去逛街的时候想到了二维的情况，如果长方形的大小是 A × B 的话，如果 A 和 B 互质，那么可以看出来，对角线穿过了 A + B &#8211; 1 个小正方形。如果 A 和 B 不互质，就求最大公约数 G, 令 A&#8217; = A / G, B&#8217; = B / G, 这么说在对角线上有 G 个 A&#8217; × B&#8217; 的长方形，对角线穿过了 (A&#8217; + B&#8217; &#8211; 1) × G 个小正方形。 推广到三维的时候就搞错了，当时想到的是，把能够从面 A 看到的小正方形的集合记为 A, 从面 B 和面 C 看到的也记为相应字母，然后能够同时从面 [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这道题的题意是，问一个由单位正方体垒成的 <em><span
style="font-family: 'times new roman', times;" >A</span></em> × <em><span
style="font-family: 'times new roman', times;" >B</span></em> × <em><span
style="font-family: 'times new roman', times;" >C</span></em> 的长方体的体对角线穿过了这个长方体中的几个单位正方体。如果对角线与正方体擦肩而过的话不算穿过。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">怎么说呢，这道题纠结了几天，网上没有题解，只有模糊地提到容斥原理。在昨晚出去逛街的时候想到了二维的情况，如果长方形的大小是 <em><span
style="font-family: 'times new roman', times;" >A</span></em> × <em><span
style="font-family: 'times new roman', times;" >B</span></em> 的话，如果 <em><span
style="font-family: 'times new roman', times;" >A</span></em> 和 <em><span
style="font-family: 'times new roman', times;" >B</span></em> 互质，那么可以看出来，对角线穿过了 <em><span
style="font-family: 'times new roman', times;" >A</span></em> + <em><span
style="font-family: 'times new roman', times;" >B</span></em> &#8211; <span
style="font-family: 'times new roman', times;" >1</span> 个小正方形。如果 <em><span
style="font-family: 'times new roman', times;" >A</span></em> 和 <em><span
style="font-family: 'times new roman', times;" >B</span></em> 不互质，就求最大公约数 <em><span
style="font-family: 'times new roman', times;" >G</span></em>, 令 <em><span
style="font-family: 'times new roman', times;" >A&#8217;</span></em> = <em><span
style="font-family: 'times new roman', times;" >A</span></em> / <em><span
style="font-family: 'times new roman', times;" >G</span></em>, <em><span
style="font-family: 'times new roman', times;" >B&#8217;</span></em> = <em><span
style="font-family: 'times new roman', times;" >B</span></em> / <em><span
style="font-family: 'times new roman', times;" >G</span></em>, 这么说在对角线上有 <em><span
style="font-family: 'times new roman', times;" >G</span></em> 个 <em><span
style="font-family: 'times new roman', times;" >A&#8217;</span></em> × <em><span
style="font-family: 'times new roman', times;" >B&#8217;</span></em> 的长方形，对角线穿过了 (<em><span
style="font-family: 'times new roman', times;" >A&#8217;</span></em> + <em><span
style="font-family: 'times new roman', times;" >B&#8217;</span></em> &#8211; <span
style="font-family: 'times new roman', times;" >1</span>) × <em><span
style="font-family: 'times new roman', times;" >G</span></em> 个小正方形。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3241" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">推广到三维的时候就搞错了，当时想到的是，把能够从面 <em><span
style="font-family: 'times new roman', times;" >A</span></em> 看到的小正方形的集合记为 <em><span
style="font-family: 'times new roman', times;" >A</span></em>, 从面 <em><span
style="font-family: 'times new roman', times;" >B</span></em> 和面 <em><span
style="font-family: 'times new roman', times;" >C</span></em> 看到的也记为相应字母，然后能够同时从面 <em><span
style="font-family: 'times new roman', times;" >A</span></em> 和面 <em><span
style="font-family: 'times new roman', times;" >B</span></em> 看到的小正方形集合记为 <em><span
style="font-family: 'times new roman', times;" >A</span></em>∩<em><span
style="font-family: 'times new roman', times;" >B</span></em>, 类似。这样就有容斥原理了：</p><blockquote><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
style="font-family: 'times new roman', times;" >card(<em>A</em>∪<em>B</em>∪<em>C</em>) = card(<em>A</em>) + card(<em>B</em>) + card(<em>C</em>) &#8211; card(<em>A</em>∩<em>B</em>) &#8211; card(<em>B</em>∩<em>C</em>) &#8211; card(<em>C</em>∩<em>A</em>) + card(<em>A</em>∩<em>B</em>∩<em>C</em>)</span>.</p></blockquote><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">在计算 <span
style="font-family: 'times new roman', times;" >card(<em>A</em>)</span> 之类的东西的时候，可以用二维的方法。但是在计算 <span
style="font-family: 'times new roman', times;" >card(<em>A</em>∩<em>B</em>)</span> 之类的时候，我一开始用的是 <span
style="font-family: 'times new roman', times;" >min(card(<em>A</em>), card(<em>B</em>))</span>, 但是后来举出了反例，所以这种方法最后还是<strong>错了</strong>。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">最后实在忍不住了，我就想应该问问当年区域赛 AC 过这题的前辈们。在看到的几份 Regional 总结中，我发现大家都说这题和当年该赛区热身赛里的一题非常像，当时的情景是几乎所有队都是齐刷刷地 AC 了这题。所以我想这也可能是这题题解较少的原因，因为当年可能大家都把它当成水题看待了……</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">凌晨一点多的时候<a
title="ICPC Hefei Regional － 悲剧？喜剧？ by watashi@ゆっくり"  href="http://watashi.ws/blog/70/icpc-hefei-regional-%EF%BC%8D-%E6%82%B2%E5%89%A7%EF%BC%9F%E5%96%9C%E5%89%A7%EF%BC%9F-by-watashi%E3%82%86%E3%81%A3%E3%81%8F%E3%82%8A/"  target="_blank" >在 watashi 大牛的博客留言请教</a>，没想到十多分钟就有了解答，感激涕零……</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这种思路还是需要一定的空间想象力，方法其实就是之前二维做法的推广，证明起来有点难，不过反正我是信了……</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;cstdio&gt;
#include &lt;algorithm&gt;
using namespace std;
template &lt;typename T&gt; T gcd(T a, T b)
{
	T r;
	while (b &gt; 0) {
		r = a % b; a = b; b = r;
	}
	return a;
}
template &lt;typename T&gt; T gcd(T a, T b, T c)
{
	return gcd(a, gcd(b, c));
}
int main()
{
	int a, b, c, r;
	while (scanf(&quot;%d %d %d&quot;, &amp;a, &amp;b, &amp;c))
	{
		if (a == 0 &amp;&amp; b == 0 &amp;&amp; c == 0)
			break;
		r = a + b + c - gcd(a, b) - gcd(b, c) - gcd(c, a) + gcd(a, b, c);
		printf(&quot;%d\n&quot;, r);
	}
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3241/acm-icpc-2009-hefei-laser-in-cuboids/" >http://euyuil.com/3241/acm-icpc-2009-hefei-laser-in-cuboids/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3241/acm-icpc-2009-hefei-laser-in-cuboids/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>ACM/ICPC 2011 北京现场赛 A Letter to Programmers 题解</title><link>http://euyuil.com/3236/acm-icpc-2011-beijing-a-letter-to-programmers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=acm-icpc-2011-beijing-a-letter-to-programmers</link> <comments>http://euyuil.com/3236/acm-icpc-2011-beijing-a-letter-to-programmers/#comments</comments> <pubDate>Sat, 11 Feb 2012 16:22:37 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[位运算]]></category> <category><![CDATA[分治]]></category> <category><![CDATA[区域赛]]></category> <category><![CDATA[现场赛]]></category> <category><![CDATA[矩阵]]></category> <category><![CDATA[递归]]></category> <category><![CDATA[题解]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3236</guid> <description><![CDATA[这道题算是一道模板题吧，思路是矩阵变换。一个问题是，怎样快速求矩阵的 n 次幂，这个可以通过分治搞定，在这题里我没有用递归的方式，而是用位运算。在遇到 repeat 命令的时候，可以用递归的方式，简化程序编写；需要注意 repeat 后面的数字只是非负的，有可能是 0. 还有记得输出的时候要判断会不会是 -0.00 这样的东西。 至于三种变换的矩阵，这里就不细说了，移动和缩放其实还是比较简单，旋转比较复杂，维基百科里有介绍。 这次在上面栽了两次，原因是 repeat 时我判断如果是 0 就直接返回了单位矩阵，而没有读到下一个 end 命令。后来为了改得方便，也没有在一开始特判 0, 所以遇到 0 的时候还是会“白算”比较多东西。不过有句话说，要避免不成熟的优化，呵呵…… 代码如下： #include &#60;cmath&#62; #include &#60;cstdio&#62; #include &#60;cstring&#62; using namespace std; const double pi = acos(-1.0); template &#60;int M, int N&#62; struct matrix { double w[M][N]; inline double &#38;operator()(int i, int j) { [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这道题算是一道模板题吧，思路是矩阵变换。一个问题是，怎样快速求矩阵的 n 次幂，这个可以通过分治搞定，在这题里我没有用递归的方式，而是用位运算。在遇到 <span
style="font-family: 'courier new', courier;" >repeat</span> 命令的时候，可以用递归的方式，简化程序编写；需要注意 <span
style="font-family: 'courier new', courier;" >repeat</span> 后面的数字只是<strong>非负</strong>的，有可能是 <span
style="font-family: 'courier new', courier;" >0</span>. 还有记得输出的时候要判断会不会是 <span
style="font-family: 'courier new', courier;" >-0.00</span> 这样的东西。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">至于三种变换的矩阵，这里就不细说了，移动和缩放其实还是比较简单，旋转比较复杂，<a
href="http://zh.wikipedia.org/zh/%E6%97%8B%E8%BD%AC%E7%9F%A9%E9%98%B5"  title="旋转矩阵 - 维基百科"  target="_blank" >维基百科</a>里有介绍。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这次在上面栽了两次，原因是 <span
style="font-family: 'courier new', courier;" >repeat</span> 时我判断如果是 0 就直接返回了单位矩阵，而没有读到下一个 <span
style="font-family: 'courier new', courier;" >end</span> 命令。后来为了改得方便，也没有在一开始特判 0, 所以遇到 0 的时候还是会“白算”比较多东西。不过有句话说，要避免不成熟的优化，呵呵……</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3236" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">代码如下：</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;cmath&gt;
#include &lt;cstdio&gt;
#include &lt;cstring&gt;
using namespace std;
const double pi = acos(-1.0);
template &lt;int M, int N&gt;
struct matrix
{
	double w[M][N];
	inline double &amp;operator()(int i, int j)
	{
		return w[i][j];
	}
	inline const double &amp;operator()(int i, int j) const
	{
		return w[i][j];
	}
	template &lt;int R&gt;
	inline matrix&lt;M, R&gt; operator*(const matrix&lt;N, R&gt; &amp;b) const
	{
		matrix&lt;M, R&gt; r;
		memset(&amp;r, 0, sizeof r);
		for (int i = 0; i &lt; M; ++i)
			for (int j = 0; j &lt; R; ++j)
				for (int k = 0; k &lt; N; ++k)
					r(i, j) += w[i][k] * b(k, j);
		return r;
	}
};
template &lt;int N&gt;
inline matrix&lt;N, N&gt; identity()
{
	matrix&lt;N, N&gt; r;
	memset(&amp;r, 0, sizeof r);
	for (int i = 0; i &lt; N; ++i)
		r(i, i) = 1.0;
	return r;
}
inline matrix&lt;4, 1&gt; vector3(double x, double y, double z)
{
	matrix&lt;4, 1&gt; r;
	memset(&amp;r, 0, sizeof r);
	r(0, 0) = x; r(1, 0) = y; r(2, 0) = z; r(3, 0) = 1.0;
	return r;
}
inline matrix&lt;4, 4&gt; translate3(double x, double y, double z)
{
	matrix&lt;4, 4&gt; r;
	memset(&amp;r, 0, sizeof r);
	r(0, 0) = 1.0; r(1, 1) = 1.0; r(2, 2) = 1.0;
	r(0, 3) = x; r(1, 3) = y; r(2, 3) = z; r(3, 3) = 1.0;
	return r;
}
inline matrix&lt;4, 4&gt; scale3(double x, double y, double z)
{
	matrix&lt;4, 4&gt; r;
	memset(&amp;r, 0, sizeof r);
	r(0, 0) = x; r(1, 1) = y; r(2, 2) = z; r(3, 3) = 1.0;
	return r;
}
inline void normalize(double &amp;x, double &amp;y, double &amp;z)
{
	double below = sqrt(x * x + y * y + z * z);
	x /= below; y /= below; z /= below;
}
inline matrix&lt;4, 4&gt; rotate3(double x, double y, double z, double a)
{
	matrix&lt;4, 4&gt; r; normalize(x, y, z);
	double cosa = cos(a), mcsa = 1.0 - cosa, sina = sin(a);
	double xy = x * y, yz = y * z, zx = z * x;
	double x2 = x * x, y2 = y * y, z2 = z * z;
	double xsna = x * sina, ysna = y * sina, zsna = z * sina;
	r(0, 0) = cosa + mcsa * x2; r(0, 1) = mcsa * xy - zsna;
	r(0, 2) = mcsa * zx + ysna; r(0, 3) = 0.0;
	r(1, 0) = mcsa * xy + zsna; r(1, 1) = cosa + mcsa * y2;
	r(1, 2) = mcsa * yz - xsna; r(1, 3) = 0.0;
	r(2, 0) = mcsa * zx - ysna; r(2, 1) = mcsa * yz + xsna;
	r(2, 2) = cosa + mcsa * z2; r(2, 3) = 0.0;
	r(3, 0) = 0.0; r(3, 1) = 0.0; r(3, 2) = 0.0; r(3, 3) = 1.0;
	return r;
}
template &lt;int N&gt; // Assumes t &gt; 1.
inline matrix&lt;N, N&gt; self_multiply(const matrix&lt;N, N&gt; &amp;a, int t)
{
	matrix&lt;N, N&gt; r = a;
	int u = t, n = 0, i;
	while (u &gt;&gt;= 1) ++n;
	for (i = n - 1; i &gt;= 0; --i)
	{
		r = r * r;
		if ((t &gt;&gt; i) &amp; 1)
			r = r * a;
	}
	return r;
}
char buffer[64];
double px, py, pz, pa;
int pt;
matrix&lt;4, 4&gt; repeat(int t)
{
	matrix&lt;4, 4&gt; r = identity&lt;4&gt;();
	while (scanf(&quot;%s&quot;, buffer))
	{
		if (!strcmp(buffer, &quot;end&quot;))
			break;
		else if (!strcmp(buffer, &quot;translate&quot;))
		{
			scanf(&quot;%lf %lf %lf&quot;, &amp;px, &amp;py, &amp;pz);
			r = translate3(px, py, pz) * r;
		}
		else if (!strcmp(buffer, &quot;scale&quot;))
		{
			scanf(&quot;%lf %lf %lf&quot;, &amp;px, &amp;py, &amp;pz);
			r = scale3(px, py, pz) * r;
		}
		else if (!strcmp(buffer, &quot;rotate&quot;))
		{
			scanf(&quot;%lf %lf %lf %lf&quot;, &amp;px, &amp;py, &amp;pz, &amp;pa);
			r = rotate3(px, py, pz, pa / 180.0 * pi) * r;
		}
		else if (!strcmp(buffer, &quot;repeat&quot;))
		{
			scanf(&quot;%d&quot;, &amp;pt);
			r = repeat(pt) * r;
		}
	}
	if (t &lt;= 0)
		return identity&lt;4&gt;();
	if (t &gt; 1)
		return self_multiply&lt;4&gt;(r, t);
	return r;
}
inline void preprocess(double &amp;a)
{
	static char buf[32];
	sprintf(buf, &quot;%0.2lf&quot;, a);
	if (!strcmp(buf, &quot;-0.00&quot;)) a = 0.0;
}
inline void print_vector3(const matrix&lt;4, 1&gt; &amp;v)
{
	double x = v(0, 0), y = v(1, 0), z = v(2, 0);
	preprocess(x); preprocess(y); preprocess(z);
	printf(&quot;%0.2lf %0.2lf %0.2lf&quot;, x, y, z);
}
inline void calculate(const matrix&lt;4, 4&gt; &amp;m, int n)
{
	while (n--)
	{
		scanf(&quot;%lf %lf %lf&quot;, &amp;px, &amp;py, &amp;pz);
		print_vector3(m * vector3(px, py, pz));
		printf(&quot;\n&quot;);
	}
}
int main()
{
	// freopen(&quot;input.txt&quot;, &quot;r&quot;, stdin);
	int n;
	while (scanf(&quot;%d&quot;, &amp;n))
	{
		if (n == 0)
			break;
		calculate(repeat(1), n);
		printf(&quot;\n&quot;);
	}
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3236/acm-icpc-2011-beijing-a-letter-to-programmers/" >http://euyuil.com/3236/acm-icpc-2011-beijing-a-letter-to-programmers/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3236/acm-icpc-2011-beijing-a-letter-to-programmers/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>ACM/ICPC 2009 武汉现场赛 Download Manager 题解</title><link>http://euyuil.com/3232/acm-icpc-2009-wuhan-download-manager/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=acm-icpc-2009-wuhan-download-manager</link> <comments>http://euyuil.com/3232/acm-icpc-2009-wuhan-download-manager/#comments</comments> <pubDate>Sat, 11 Feb 2012 04:42:05 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[优先队列]]></category> <category><![CDATA[区域赛]]></category> <category><![CDATA[堆]]></category> <category><![CDATA[模拟]]></category> <category><![CDATA[现场赛]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3232</guid> <description><![CDATA[这是一道模拟的题目。 我的思路是，用两个优先队列，一个是正在下载的文件的队列，另一个是等待下载的文件的队列。对于正在下载的文件队列，维护“所剩字节数最少的那个文件”在堆顶；对于等待下载的文件的队列，维护题目中所描述的那种最优先被下载的文件在堆顶。 然后循环，看正在下载的文件队列是否满，未满则将等待被下载的文件队列中的文件一个个弹出又插入到正在下载的队列。再看那个所剩字节最少的文件，让每个文件都减掉那么多字节，然后把那些字节为 0（即下载完了的）文件删掉，再把所需时间加到计数器。最后循环啊循环就好了。 这道题有一个阴险的地方是： Print a blank line after the output of each test case. 害我 WA 了两次…… #include &#60;queue&#62; #include &#60;cstdio&#62; #include &#60;vector&#62; #include &#60;algorithm&#62; using namespace std; struct file { double size, progress, remain; inline file(double sz, double pg) : size(sz), progress(pg) { remain = size - size * progress / 100.0; [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这是一道模拟的题目。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">我的思路是，用两个优先队列，一个是正在下载的文件的队列，另一个是等待下载的文件的队列。对于正在下载的文件队列，维护“所剩字节数最少的那个文件”在堆顶；对于等待下载的文件的队列，维护题目中所描述的那种最优先被下载的文件在堆顶。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">然后循环，看正在下载的文件队列是否满，未满则将等待被下载的文件队列中的文件一个个弹出又插入到正在下载的队列。再看那个所剩字节最少的文件，让每个文件都减掉那么多字节，然后把那些字节为 0（即下载完了的）文件删掉，再把所需时间加到计数器。最后循环啊循环就好了。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3232" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这道题有一个阴险的地方是：</p><blockquote><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">Print a blank line after the output of each test case.</p></blockquote><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">害我 WA 了两次……</p><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;queue&gt;
#include &lt;cstdio&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
using namespace std;
struct file
{
	double size, progress, remain;
	inline file(double sz, double pg) : size(sz), progress(pg)
	{
		remain = size - size * progress / 100.0;
	}
	inline bool operator&lt;=(const file &amp;b) const
	{
		if (size == b.size)
			return progress &gt;= b.progress;
		return size &lt;= b.size;
	}
};
class download_priority {
public:
	inline bool operator()(const file &amp;a, const file &amp;b) {
		return b &lt;= a;
	}
};
class remaining_size {
public:
	inline bool operator()(const file &amp;a, const file &amp;b) {
		return a.remain &gt;= b.remain;
	}
};
int file_count, max_download; double bandwidth;
vector&lt;file&gt; download_slot;
priority_queue&lt;file, vector&lt;file&gt;, download_priority&gt; download_queue;
inline void fill_download_slot()
{
	while (download_slot.size() &lt; max_download &amp;&amp; !download_queue.empty())
	{
		download_slot.push_back(download_queue.top()); download_queue.pop();
		push_heap(download_slot.begin(), download_slot.end(), remaining_size());
	}
}
inline void decrease_remain_by(double size)
{
	for (int i = 0; i &lt; download_slot.size(); ++i)
		download_slot[i].remain -= size;
}
inline void remove_downloaded_files()
{
	while (!download_slot.empty() &amp;&amp; download_slot[0].remain &lt;= 0.0)
	{
		pop_heap(download_slot.begin(), download_slot.end(), remaining_size());
		download_slot.pop_back();
	}
}
inline double download_time()
{
	double second = 0.0;
	while (!download_slot.empty() || !download_queue.empty())
	{
		fill_download_slot();
		double bandwidth_each = bandwidth / (double)download_slot.size();
		// File with least download-time will be download_slot[0].
		double remain_size = download_slot[0].remain;
		double remain_time = remain_size / bandwidth_each;
		decrease_remain_by(remain_size);
		remove_downloaded_files();
		second += remain_time;
	}
	return second;
}
inline bool init_and_input()
{
	scanf(&quot;%d %d %lf&quot;, &amp;file_count, &amp;max_download, &amp;bandwidth);
	if (file_count == 0.0 &amp;&amp; max_download == 0.0 &amp;&amp; bandwidth == 0.0)
		return false;
	for (int i = 0; i &lt; file_count; ++i)
	{
		double size, progress;
		scanf(&quot;%lf %lf&quot;, &amp;size, &amp;progress);
		download_queue.push(file(size, progress));
	}
	return true;
}
int main()
{
	// freopen(&quot;input.txt&quot;, &quot;r&quot;, stdin);
	int i = 0;
	while (init_and_input())
		printf(&quot;Case %d: %0.2lf\n\n&quot;, ++i, download_time());
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3232/acm-icpc-2009-wuhan-download-manager/" >http://euyuil.com/3232/acm-icpc-2009-wuhan-download-manager/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3232/acm-icpc-2009-wuhan-download-manager/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>ACM/ICPC 2011 成都现场赛 Holiday Accommodation 题解</title><link>http://euyuil.com/3227/acm-icpc-2011-chengdu-holiday-accommodation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=acm-icpc-2011-chengdu-holiday-accommodation</link> <comments>http://euyuil.com/3227/acm-icpc-2011-chengdu-holiday-accommodation/#comments</comments> <pubDate>Fri, 10 Feb 2012 14:55:12 +0000</pubDate> <dc:creator>EUYUIL</dc:creator> <category><![CDATA[无类可分]]></category> <category><![CDATA[ACM]]></category> <category><![CDATA[区域赛]]></category> <category><![CDATA[图论]]></category> <category><![CDATA[数据生成器]]></category> <category><![CDATA[无向图]]></category> <category><![CDATA[栈模拟递归]]></category> <category><![CDATA[深度优先搜索]]></category> <category><![CDATA[现场赛]]></category> <guid
isPermaLink="false">http://euyuil.com/?p=3227</guid> <description><![CDATA[图论题，思路就是，首先把每条边的两端的顶点数统计出来，并且取较小的那一个数，这个数的含义是，最多会有多少对 family 路过这条路。然后用这些数乘以它相应的权值，再乘以 2 就可以了。 由于极端情况下，节点数会达到 105, 路径长度会达到 106, 这已经明显超过 32 位整型了。所以需要用 long long. 需要注意的地方就是，如果两个 int 相乘，其结果可能会达到 long long 的话，那么先把两个 int 分别转换成 long long 再乘。至于为什么就不多解释了。 还有极端情况，比如整棵树退化成了链，100,000 个节点要是深搜的话，就 stack overflow 了。所以需要用栈模拟递归。但是我记得我们队的 WH 在某次练习的时候，用深搜成功解决了这个问题，这有两个方面的原因：一个是他的 dfs 函数没有返回值，并且只有一个参数；二是他是从中间那个顶点开始进行深搜的。所以，他骗分导论学得不错啊。 这道题我 WA 了几次，有因为数组开小了，有因为没有使用栈模拟递归的，还有因为没看清到底是应该使用 %lld 还是 %I64d 的。所以以后一定要吸取教训。 还有就是这道题我写了一个数据生成器，树结构的数据生成器还是比较麻烦。 本题源代码 #include &#60;cstdio&#62; #include &#60;cstring&#62; #include &#60;algorithm&#62; using namespace std; typedef unsigned long [...]]]></description> <content:encoded><![CDATA[<p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">图论题，思路就是，首先把每条边的两端的顶点数统计出来，并且取较小的那一个数，这个数的含义是，最多会有多少对 family 路过这条路。然后用这些数乘以它相应的权值，再乘以 2 就可以了。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">由于极端情况下，节点数会达到 10<sup>5</sup>, 路径长度会达到 10<sup>6</sup>, 这已经明显超过 32 位整型了。所以需要用 <span
style="font-family: 'courier new', courier;" >long long</span>. 需要注意的地方就是，如果两个 <span
style="font-family: 'courier new', courier;" >int</span> 相乘，其结果可能会达到 <span
style="font-family: 'courier new', courier;" >long long</span> 的话，那么先把两个 <span
style="font-family: 'courier new', courier;" >int</span> 分别转换成 <span
style="font-family: 'courier new', courier;" >long long</span> 再乘。至于为什么就不多解释了。</sup></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><span
id="more-3227" ></span></p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">还有极端情况，比如整棵树退化成了链，100,000 个节点要是深搜的话，就 stack overflow 了。所以需要用栈模拟递归。但是我记得我们队的 WH 在某次练习的时候，用深搜成功解决了这个问题，这有两个方面的原因：一个是他的 <span
style="font-family: 'courier new', courier;" >dfs</span> 函数没有返回值，并且只有一个参数；二是他是从中间那个顶点开始进行深搜的。所以，他骗分导论学得不错啊。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">这道题我 WA 了几次，有因为数组开小了，有因为没有使用栈模拟递归的，还有因为没看清到底是应该使用 <span
style="font-family: 'courier new', courier;" >%lld</span> 还是 <span
style="font-family: 'courier new', courier;" >%I64d</span> 的。所以以后一定要吸取教训。</p><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;">还有就是这道题我写了一个数据生成器，树结构的数据生成器还是比较麻烦。</p><h2>本题源代码</h2><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;cstdio&gt;
#include &lt;cstring&gt;
#include &lt;algorithm&gt;
using namespace std;
typedef unsigned long long ull;
const int N = 222222;
const int M = N &lt;&lt; 1;
struct glist
{
	int n, m, fe[N], ne[M], he[M], ev[M];
	inline void reset(int sz = 0)
	{
		memset(fe, -1, sizeof fe);
		n = sz; m = 0;
	}
	inline void insert_directed(int u, int v, int w)
	{
		he[m] = v;
		ev[m] = w;
		ne[m] = fe[u];
		fe[u] = m++;
	}
	inline void insert(int u, int v, int w)
	{
		insert_directed(u, v, w);
		insert_directed(v, u, w);
	}
};
glist g; int enc[M]; // Edge node count.
struct { int v, e, r; } stk[N]; bool vst[N];
inline void count_node(int index)
{
	int t = 0, w, cnt;
	memset(enc, 0, sizeof enc);
	memset(vst, false, sizeof vst);
	stk[0].v = index; // init stack.
__0:
	vst[stk[t].v] = true;
	stk[t].r = 1; // result = 1;
	stk[t].e = g.fe[stk[t].v];
	while (stk[t].e != -1)
	{
		w = g.he[stk[t].e];
		if (!vst[w])
		{
			++t; stk[t].v = w; goto __0; // ? = dfs(w);
__1:
			cnt = stk[t+1].r; // cnt = dfs(w);
			stk[t].r += cnt; // result += cnt;
			enc[stk[t].e&gt;&gt;1] = min(cnt, g.n - cnt);
		}
		stk[t].e = g.ne[stk[t].e];
	}
	if (t &gt; 0)
	{
		--t; goto __1; // return result;
	}
}
int main()
{
	// freopen(&quot;input.txt&quot;, &quot;r&quot;, stdin);
	// freopen(&quot;output.txt&quot;, &quot;w&quot;, stdout);
	int T, n;
	scanf(&quot;%d&quot;, &amp;T);
	for (int k = 1; k &lt;= T; ++k)
	{
		scanf(&quot;%d&quot;, &amp;n);
		g.reset(n);
		for (int i = 1; i &lt; n; ++i)
		{
			int u, v, w;
			scanf(&quot;%d %d %d&quot;, &amp;u, &amp;v, &amp;w);
			--u; --v;
			g.insert(u, v, w);
		}
		count_node(0);
		ull result = 0;
		for (int i = 0; i &lt; g.m; i += 2)
			result += ull(enc[i&gt;&gt;1]) * ull(g.ev[i]);
		printf(&quot;Case #%d: %llu\n&quot;, k, (result * 2ull));
	}
	return 0;
}</code></pre><h2>数据生成器源代码</h2><pre class="crayon-plain-tag"   style="padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono'padding:.5em 1em;border:solid 1px #9f9f9f;background:#f1f1f1;margin-left:1em;font-family:'Yahei Mono''Yahei Consolas Hybrid''Yahei Consolas Hybrid'ConsolasConsolas'Courier New''Courier New'monospace;monospace;"><code>#include &lt;iostream&gt;
#include &lt;cstdlib&gt;
#include &lt;cstdio&gt;
#include &lt;ctime&gt;
using namespace std;
const int N = 111111;
inline int rnd()
{
	return (rand() * rand()) &amp; 0x7fffffff;
}
struct tree_generator
{
	int r[N], n;
	inline void reset(int sz)
	{
		n = sz;
		for (int i = 0; i &lt; n; ++i)
			r[i] = i;
	}
	int find(int x)
	{
		return r[x] = (x == r[x] ? x : find(r[x]));
	}
	inline void merge(int x, int y)
	{
		r[find(x)] = find(y);
	}
	inline void generate()
	{
		int x, y, w, k; bool flag = true;
		for (int i = 1; i &lt; n; ++i)
		{
			k = 0; flag = true;
			do
			{
				if (++k &lt; 100)
					x = rnd() % n;
				else
					for (x = 0; flag; ++x)
					{
						if (find(x) == x)
						{
							if (rand() &amp; 1) break;
							for ( ; find(x) != x; ++x);
							flag = false;
						}
					}
				y = rnd() % n;
			}
			while (find(x) == find(y));
			w = rnd() % 1000000 + 1;
			cout &lt;&lt; x + 1 &lt;&lt; ' ' &lt;&lt; y + 1 &lt;&lt; ' ' &lt;&lt; w &lt;&lt; endl;
			merge(x, y);
			if (!(i % 1000)) cerr &lt;&lt; i &lt;&lt; ' ';
		}
	}
};
tree_generator generator;
int main()
{
	freopen(&quot;input.txt&quot;, &quot;w&quot;, stdout);
	srand((unsigned int)time(NULL));
	int T = 10;
	cout &lt;&lt; T &lt;&lt; endl &lt;&lt; endl;
	while (T--)
	{
		unsigned int n = rnd() % 98765 + 3;
		cout &lt;&lt; n &lt;&lt; endl &lt;&lt; endl;
		cerr &lt;&lt; &quot;==== &quot; &lt;&lt; T &lt;&lt; ':' &lt;&lt; n &lt;&lt; endl;
		generator.reset(n);
		generator.generate();
		cout &lt;&lt; endl &lt;&lt; endl;
		cerr &lt;&lt; endl &lt;&lt; endl;
	}
	return 0;
}</code></pre><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><div
style="margin-top:15px;" ><p
style="margin:0;padding:0;line-height:1.75em;text-indent:2em;margin:0;padding:0;line-height:1.75em;text-indent:2em;"><strong>原创文章，转载请注明来源：</strong><a
href="http://euyuil.com/3227/acm-icpc-2011-chengdu-holiday-accommodation/" >http://euyuil.com/3227/acm-icpc-2011-chengdu-holiday-accommodation/</a></p></div> ]]></content:encoded> <wfw:commentRss>http://euyuil.com/3227/acm-icpc-2011-chengdu-holiday-accommodation/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Dynamic page generated in 2.186 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-22 22:41:27 -->
<!-- Compression = gzip -->
