fork(1) download
  1. /* paiza POH! vol.2
  2.  * result:
  3.  * http://p...content-available-to-author-only...a.jp/poh/paizen/result/ae22de69aa40d92d7f9a4b395dc2649d
  4.  * author: Leonardone @ NEETSDKASU
  5.  */
  6. import java.util.*;
  7. import java.lang.*;
  8. import java.lang.ref.*;
  9. import java.io.*;
  10.  
  11.  
  12. class Main
  13. {
  14. public static void main (String[] args) throws java.lang.Exception
  15. {
  16.  
  17. String[] hw = in.readLine().split(" ");
  18. int H = Integer.parseInt(hw[0]); // ホーム画面縦の区画数
  19. int W = Integer.parseInt(hw[1]); // ホーム画面横の区画数
  20.  
  21. int[][] home = new int[H][W];
  22.  
  23. for (int y = 0; y < H; y++)
  24. {
  25. String line = in.readLine();
  26. for (int x = 0; x < W; x++)
  27. {
  28. home[y][x] = (int)(line.charAt(x) - '0');
  29. }
  30. }
  31.  
  32. int N = Integer.parseInt(in.readLine()); // ウィジェット数
  33.  
  34. WidgetTree tree = new WidgetTree();
  35. Set<Widget> set = new HashSet<Widget>(N);
  36. Queue<Widget> queue = new ArrayDeque<Widget>(N);
  37.  
  38. for (int i = 0; i < N; i++)
  39. {
  40. String[] st = in.readLine().split(" ");
  41. int s = Integer.parseInt(st[0]); // ウィジェットの縦サイズ
  42. int t = Integer.parseInt(st[1]); // ウィジェットの横サイズ
  43.  
  44. Widget widget = Widget.getWidget(s, t);
  45.  
  46. if (set.add(widget))
  47. {
  48. tree.add(widget);
  49. }
  50.  
  51. queue.offer(widget);
  52. }
  53.  
  54. tree.calc(home);
  55.  
  56. for (Widget widget : queue)
  57. {
  58. System.out.println(widget.getAnswer());
  59. }
  60.  
  61. } // end of main(String[])
  62. }
  63.  
  64.  
  65. class Widget
  66. {
  67. private static Widget[] pool = new Widget[90604];
  68.  
  69. public static Widget getWidget(int s, int t)
  70. {
  71. int index = s * 301 + t;
  72. if (pool[index] == null)
  73. {
  74. pool[index] = new Widget(s, t);
  75. }
  76. return pool[index];
  77. }
  78.  
  79. private final int s;
  80. private final int t;
  81. private int answer = 0;
  82. private Widget(int s, int t)
  83. {
  84. this.s = s;
  85. this.t = t;
  86. }
  87.  
  88. public int getS()
  89. {
  90. return s;
  91. }
  92.  
  93. public int getT()
  94. {
  95. return t;
  96. }
  97.  
  98. public int getAnswer()
  99. {
  100. return answer;
  101. }
  102.  
  103. public int setAnswer(int answer)
  104. {
  105. this.answer = answer;
  106. return answer;
  107. }
  108.  
  109. @Override
  110. public int hashCode()
  111. {
  112. return s * 301 + t;
  113. }
  114.  
  115. @Override
  116. public boolean equals(Object obj)
  117. {
  118. if (this == obj) return true;
  119. if (obj == null) return false;
  120. if (this.getClass().equals(obj.getClass()) == false) return false;
  121. Widget widget = (Widget)obj;
  122. return this.s == widget.s && this.t == widget.t;
  123. }
  124.  
  125. @Override
  126. public String toString()
  127. {
  128. return "[" + s + "," + t + "]";
  129. }
  130.  
  131. public enum Extend
  132. {
  133. S_PARENT, S_CHILD, T_PARENT, T_CHILD,
  134. SAME, IMPOSSIBLE, PRE_T_CHILD, PRE_S_CHILD,
  135. PRE_PARENT
  136. }
  137.  
  138. public Extend getExtend(Widget widget)
  139. {
  140. if (this.s == widget.s && this.t == widget.t)
  141. {
  142. return Extend.SAME;
  143. }
  144. if (this.s == widget.s)
  145. {
  146. if (this.t < widget.t)
  147. {
  148. return Extend.T_CHILD;
  149. }
  150. return Extend.T_PARENT;
  151. }
  152. if (this.t == widget.t)
  153. {
  154. if (this.s < widget.s)
  155. {
  156. return Extend.S_CHILD;
  157. }
  158. return Extend.S_PARENT;
  159. }
  160. if (this.s < widget.s && this.t < widget.t)
  161. {
  162. if (widget.s < widget.t)
  163. {
  164. return Extend.PRE_T_CHILD;
  165. }
  166. return Extend.PRE_S_CHILD;
  167. }
  168. if (this.s > widget.s && this.t > widget.t)
  169. {
  170. return Extend.PRE_PARENT;
  171. }
  172. return Extend.IMPOSSIBLE;
  173. }
  174. }
  175.  
  176. class WidgetTree
  177. {
  178. private class Node
  179. {
  180. final Widget widget;
  181. WeakReference<Node> t_parent = null;
  182. WeakReference<Node> s_parent = null;
  183. Node t_child = null;
  184. Node s_child = null;
  185. Queue<Node> pre_s_child = new ArrayDeque<Node>();
  186. Queue<Node> pre_t_child = new ArrayDeque<Node>();
  187. Node(Widget widget)
  188. {
  189. this.widget = widget;
  190. }
  191.  
  192. @Override
  193. public String toString()
  194. {
  195. return "<" + widget + ";" + t_child
  196. + ";" + s_child + ";("
  197. + pre_t_child + ");(" + pre_s_child + ")>";
  198. }
  199. }
  200.  
  201. private Node root = new Node(Widget.getWidget(1,1));
  202.  
  203. @Override
  204. public String toString()
  205. {
  206. return root.toString();
  207. }
  208.  
  209. private enum Family { T_FAMILY, S_FAMILY }
  210.  
  211. private boolean setFamily(Node parent, Node child, Family family)
  212. {
  213. if (parent == null || child == null || family == null)
  214. {
  215. return false;
  216. }
  217. switch (family)
  218. {
  219. case T_FAMILY:
  220. parent.t_child = child;
  221. child.t_parent = new WeakReference<Node>(parent);
  222. break;
  223. case S_FAMILY:
  224. parent.s_child = child;
  225. child.s_parent = new WeakReference<Node>(parent);
  226. break;
  227. default:
  228. return false;
  229. }
  230. return true;
  231. }
  232.  
  233. private Node joint(Node node1, Node node2)
  234. {
  235.  
  236. Node temp = null, temp2 = null, temp3 = null;
  237. int n;
  238.  
  239. Widget.Extend e = node1.widget.getExtend(node2.widget);
  240. switch (e)
  241. {
  242. case T_PARENT:
  243. {
  244. if (node2.t_child != null)
  245. {
  246. temp = joint(node2.t_child, node1);
  247. setFamily(node2, temp, Family.T_FAMILY);
  248. }
  249. else
  250. {
  251. setFamily(node2, node1, Family.T_FAMILY);
  252. }
  253. n = node2.pre_t_child.size();
  254. for (int i = 0; i < n; i++)
  255. {
  256. temp2 = node2.pre_t_child.poll();
  257. temp3 = joint(node2.t_child, temp2);
  258. if (temp3 == null)
  259. {
  260. node2.pre_t_child.offer(temp2);
  261. }
  262. else
  263. {
  264. setFamily(node2, temp3, Family.T_FAMILY);
  265. }
  266. }
  267. return node2;
  268. }
  269. case S_PARENT:
  270. {
  271. if (node2.s_child != null)
  272. {
  273. temp = joint(node2.s_child, node1);
  274. setFamily(node2, temp, Family.S_FAMILY);
  275. }
  276. else
  277. {
  278. setFamily(node2, node1, Family.S_FAMILY);
  279. }
  280. n = node2.pre_s_child.size();
  281. for (int i = 0; i < n; i++)
  282. {
  283. temp2 = node2.pre_s_child.poll();
  284. temp3 = joint(node2.s_child, temp2);
  285. if (temp3 == null)
  286. {
  287. node2.pre_s_child.offer(temp2);
  288. }
  289. else
  290. {
  291. setFamily(node2, temp3, Family.S_FAMILY);
  292. }
  293. }
  294. return node2;
  295. }
  296. case T_CHILD:
  297. case S_CHILD:
  298. {
  299. return joint(node2, node1);
  300. }
  301. case PRE_S_CHILD:
  302. {
  303. if (node1.s_child != null)
  304. {
  305. temp = joint(node1.s_child, node2);
  306. setFamily(node1, temp, Family.S_FAMILY);
  307. }
  308. if (temp == null)
  309. {
  310. if (node1.pre_s_child.isEmpty())
  311. {
  312. node1.pre_s_child.offer(node2);
  313. }
  314. else
  315. {
  316. n = node1.pre_s_child.size();
  317. for (int i = 0; i < n; i++)
  318. {
  319. temp2 = node1.pre_s_child.poll();
  320. temp3 = joint(temp2, node2);
  321. if (temp3 != null)
  322. {
  323. node1.pre_s_child.offer(temp3);
  324. break;
  325. }
  326. node1.pre_s_child.offer(temp2);
  327. }
  328. if (temp3 == null)
  329. {
  330. node1.pre_s_child.offer(node2);
  331. }
  332. }
  333. }
  334. return node1;
  335. }
  336. case PRE_T_CHILD:
  337. {
  338. if (node1.t_child != null)
  339. {
  340. temp = joint(node1.t_child, node2);
  341. setFamily(node1, temp, Family.T_FAMILY);
  342. }
  343. if (temp == null)
  344. {
  345. if (node1.pre_t_child.isEmpty())
  346. {
  347. node1.pre_t_child.offer(node2);
  348. }
  349. else
  350. {
  351. n = node1.pre_t_child.size();
  352. for (int i = 0; i < n; i++)
  353. {
  354. temp2 = node1.pre_t_child.poll();
  355. temp3 = joint(temp2, node2);
  356. if (temp3 != null)
  357. {
  358. node1.pre_t_child.offer(temp3);
  359. break;
  360. }
  361. else
  362. {
  363. node1.pre_t_child.offer(temp2);
  364. }
  365. }
  366. if (temp3 == null)
  367. {
  368. node1.pre_t_child.offer(node2);
  369. }
  370. }
  371. }
  372. return node1;
  373. }
  374. case SAME:
  375. {
  376. return node1;
  377. }
  378. case PRE_PARENT:
  379. case IMPOSSIBLE:
  380. default:
  381. {
  382. break;
  383. }
  384. }
  385. return null;
  386. }
  387.  
  388.  
  389. public boolean add(Widget widget)
  390. {
  391. Node temp = joint(root, new Node(widget));
  392. if (temp == null)
  393. {
  394. return false;
  395. }
  396. root = temp;
  397. return true;
  398. }
  399.  
  400. private void calc(Node parent, Node child, int[][]array)
  401. {
  402. calc(child, parent.widget.getS(), parent.widget.getT(), array);
  403. }
  404.  
  405.  
  406. private void calc(Node node, int s, int t, int[][] array)
  407. {
  408. if (node == null)
  409. {
  410. return;
  411. }
  412. int ds = node.widget.getS() - s;
  413. int dt = node.widget.getT() - t;
  414. int[][] temp = new int[array.length - ds][array[0].length - dt];
  415. int count = 0;
  416. for (int i = 0; i < temp.length; i++)
  417. {
  418. for (int j = 0; j < temp[0].length; j++)
  419. {
  420. for (int dy = 0; dy <= ds; dy++)
  421. {
  422. for (int dx = 0; dx <= dt; dx++)
  423. {
  424. temp[i][j] += array[i + dy][j + dx];
  425. }
  426. }
  427. if (temp[i][j] == 0)
  428. {
  429. count++;
  430. }
  431. }
  432. }
  433. node.widget.setAnswer(count);
  434. calc(node, node.t_child, temp);
  435. calc(node, node.s_child, temp);
  436. for (Node p : node.pre_t_child)
  437. {
  438. calc(node, p, temp);
  439. }
  440. for (Node p : node.pre_s_child)
  441. {
  442. calc(node, p, temp);
  443. }
  444. }
  445.  
  446. public void calc(int[][] home)
  447. {
  448. calc(root, 1, 1, home);
  449. }
  450. }
  451.  
  452.  
Success #stdin #stdout 0.08s 380160KB
stdin
5 5
00000
00100
00010
10001
10000
7
2 2
1 1
3 2
3 2
2 3
3 1
1 3
stdout
6
20
2
2
1
6
7