fork(1) download
  1. /* paiza POH! vol.2
  2.  * result:
  3.  * http://p...content-available-to-author-only...a.jp/poh/paizen/result/06c9795c98d4f4264bb72791c55c59e7
  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. Widget[] list = new 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. list[i] = Widget.getWidget(s, t);
  45.  
  46. if (s <= H && t <= W)
  47. {
  48. if (set.add(list[i]))
  49. {
  50. tree.add(list[i]);
  51. }
  52. }
  53.  
  54. }
  55.  
  56. tree.calc(H, W, home);
  57.  
  58. // System.out.println(tree);
  59.  
  60. for (Widget widget : list)
  61. {
  62. System.out.println(widget.getAnswer());
  63. }
  64.  
  65. } // end of main(String[])
  66. }
  67.  
  68.  
  69. class Widget
  70. {
  71. private static Widget[] pool = new Widget[90604];
  72.  
  73. public static Widget getWidget(int s, int t)
  74. {
  75. int index = s * 301 + t;
  76. if (pool[index] == null)
  77. {
  78. pool[index] = new Widget(s, t);
  79. }
  80. return pool[index];
  81. }
  82.  
  83. private final int s;
  84. private final int t;
  85. private int answer = 0;
  86. private Widget(int s, int t)
  87. {
  88. this.s = s;
  89. this.t = t;
  90. }
  91.  
  92. public int getS()
  93. {
  94. return s;
  95. }
  96.  
  97. public int getT()
  98. {
  99. return t;
  100. }
  101.  
  102. public int getAnswer()
  103. {
  104. return answer;
  105. }
  106.  
  107. public int setAnswer(int answer)
  108. {
  109. this.answer = answer;
  110. return answer;
  111. }
  112.  
  113. @Override
  114. public int hashCode()
  115. {
  116. return s * 301 + t;
  117. }
  118.  
  119. @Override
  120. public boolean equals(Object obj)
  121. {
  122. if (this == obj) return true;
  123. if (obj == null) return false;
  124. if (this.getClass().equals(obj.getClass()) == false) return false;
  125. Widget widget = (Widget)obj;
  126. return this.s == widget.s && this.t == widget.t;
  127. }
  128.  
  129. @Override
  130. public String toString()
  131. {
  132. return "[" + s + "," + t + "]";
  133. }
  134.  
  135. public enum Extend
  136. {
  137. S_PARENT, S_CHILD, T_PARENT, T_CHILD,
  138. SAME, IMPOSSIBLE, PRE_T_CHILD, PRE_S_CHILD,
  139. PRE_PARENT
  140. }
  141.  
  142. public Extend getExtend(Widget widget)
  143. {
  144. if (this.s == widget.s && this.t == widget.t)
  145. {
  146. return Extend.SAME;
  147. }
  148. if (this.s == widget.s)
  149. {
  150. if (this.t < widget.t)
  151. {
  152. return Extend.T_CHILD;
  153. }
  154. return Extend.T_PARENT;
  155. }
  156. if (this.t == widget.t)
  157. {
  158. if (this.s < widget.s)
  159. {
  160. return Extend.S_CHILD;
  161. }
  162. return Extend.S_PARENT;
  163. }
  164. if (this.s < widget.s && this.t < widget.t)
  165. {
  166. if (widget.s < widget.t)
  167. {
  168. return Extend.PRE_T_CHILD;
  169. }
  170. return Extend.PRE_S_CHILD;
  171. }
  172. if (this.s > widget.s && this.t > widget.t)
  173. {
  174. return Extend.PRE_PARENT;
  175. }
  176. return Extend.IMPOSSIBLE;
  177. }
  178. }
  179.  
  180. class WidgetTree
  181. {
  182. private class Node
  183. {
  184. final Widget widget;
  185. Node t_child = null;
  186. Node s_child = null;
  187. Queue<Node> pre_s_child = null;
  188. Queue<Node> pre_t_child = null;
  189. Node(Widget widget)
  190. {
  191. this.widget = widget;
  192. }
  193.  
  194. public int childrenCount()
  195. {
  196. int c = (t_child != null ? 1 : 0)
  197. + (s_child != null ? 1: 0);
  198. if (pre_s_child != null)
  199. {
  200. c += pre_s_child.size();
  201. }
  202. if (pre_t_child != null)
  203. {
  204. c += pre_t_child.size();
  205. }
  206. return c;
  207. }
  208.  
  209. @Override
  210. public String toString()
  211. {
  212. return "<" + widget + ";" + t_child
  213. + ";" + s_child + ";("
  214. + pre_t_child + ");(" + pre_s_child + ")>";
  215. }
  216. }
  217.  
  218. private Node root = new Node(Widget.getWidget(1,1));
  219.  
  220. @Override
  221. public String toString()
  222. {
  223. return root.toString();
  224. }
  225.  
  226. private enum Family { T_FAMILY, S_FAMILY }
  227.  
  228. private Node setFamily(Node parent, Node child, Family family)
  229. {
  230. if (parent == null || child == null || family == null)
  231. {
  232. return parent;
  233. }
  234. switch (family)
  235. {
  236. case T_FAMILY:
  237. parent.t_child = child;
  238. break;
  239. case S_FAMILY:
  240. parent.s_child = child;
  241. break;
  242. default:
  243. break;
  244. }
  245. return parent;
  246. }
  247.  
  248. private Node joint(Node node1, Node node2)
  249. {
  250.  
  251. Node temp = null, temp2 = null, temp3 = null;
  252. int n;
  253.  
  254. Widget.Extend e = node1.widget.getExtend(node2.widget);
  255. switch (e)
  256. {
  257. case T_PARENT:
  258. {
  259. if (node2.pre_t_child != null)
  260. {
  261. n = node2.pre_t_child.size();
  262. for (int i = 0; i < n; i++)
  263. {
  264. temp2 = node2.pre_t_child.poll();
  265. temp3 = joint(node1, temp2);
  266. if (temp3 == null)
  267. {
  268. node2.pre_t_child.offer(temp2);
  269. }
  270. else
  271. {
  272. if (node1 != temp3)
  273. {
  274. node2.pre_t_child.offer(temp3);
  275. return node2;
  276. }
  277. }
  278. }
  279. }
  280. if (node2.t_child != null)
  281. {
  282. temp = joint(node2.t_child, node1);
  283. setFamily(node2, temp, Family.T_FAMILY);
  284. }
  285. else
  286. {
  287. setFamily(node2, node1, Family.T_FAMILY);
  288. }
  289. return node2;
  290. }
  291. case S_PARENT:
  292. {
  293. if (node2.pre_s_child != null)
  294. {
  295. n = node2.pre_s_child.size();
  296. for (int i = 0; i < n; i++)
  297. {
  298. temp2 = node2.pre_s_child.poll();
  299. temp3 = joint(node1, temp2);
  300. if (temp3 == null)
  301. {
  302. node2.pre_s_child.offer(temp2);
  303. }
  304. else
  305. {
  306. if (node1 != temp3)
  307. {
  308. node2.pre_s_child.offer(temp3);
  309. return node2;
  310. }
  311. }
  312. }
  313. }
  314. if (node2.s_child != null)
  315. {
  316. temp = joint(node2.s_child, node1);
  317. setFamily(node2, temp, Family.S_FAMILY);
  318. }
  319. else
  320. {
  321. setFamily(node2, node1, Family.S_FAMILY);
  322. }
  323. return node2;
  324. }
  325. case T_CHILD:
  326. case S_CHILD:
  327. {
  328. return joint(node2, node1);
  329. }
  330. case PRE_S_CHILD:
  331. {
  332. if (node1.pre_s_child != null)
  333. {
  334. n = node1.pre_s_child.size();
  335. for (int i = 0; i < n; i++)
  336. {
  337. temp2 = node1.pre_s_child.poll();
  338. temp3 = joint(node2, temp2);
  339. if (temp3 == null)
  340. {
  341. node1.pre_s_child.offer(temp2);
  342. }
  343. else
  344. {
  345. if (temp3 != node2)
  346. {
  347. node1.pre_s_child.offer(temp3);
  348. return node1;
  349. }
  350. }
  351. }
  352. }
  353. if (node1.s_child != null)
  354. {
  355. temp = joint(node1.s_child, node2);
  356. setFamily(node1, temp, Family.S_FAMILY);
  357. }
  358. if (temp == null)
  359. {
  360. if (node1.pre_s_child == null)
  361. {
  362. node1.pre_s_child = new ArrayDeque<Node>();
  363. }
  364. node1.pre_s_child.offer(node2);
  365. }
  366. return node1;
  367. }
  368. case PRE_T_CHILD:
  369. {
  370. if (node1.pre_t_child != null)
  371. {
  372. n = node1.pre_t_child.size();
  373. for (int i = 0; i < n; i++)
  374. {
  375. temp2 = node1.pre_t_child.poll();
  376. temp3 = joint(node2, temp2);
  377. if (temp3 == null)
  378. {
  379. node1.pre_t_child.offer(temp2);
  380. }
  381. else
  382. {
  383. if (temp3 != node2)
  384. {
  385. node1.pre_t_child.offer(temp3);
  386. return node1;
  387. }
  388. }
  389. }
  390. }
  391. if (node1.t_child != null)
  392. {
  393. temp = joint(node1.t_child, node2);
  394. setFamily(node1, temp, Family.T_FAMILY);
  395. }
  396. if (temp == null)
  397. {
  398. if (node1.pre_t_child == null)
  399. {
  400. node1.pre_t_child = new ArrayDeque<Node>();
  401. }
  402. node1.pre_t_child.offer(node2);
  403. }
  404. return node1;
  405. }
  406. case SAME:
  407. {
  408. return node1;
  409. }
  410. case PRE_PARENT:
  411. case IMPOSSIBLE:
  412. default:
  413. {
  414. break;
  415. }
  416. }
  417. return null;
  418. }
  419.  
  420.  
  421. public boolean add(Widget widget)
  422. {
  423. Node temp = joint(root, new Node(widget));
  424. if (temp == null)
  425. {
  426. return false;
  427. }
  428. root = temp;
  429. return true;
  430. }
  431.  
  432. private void calc(Node parent, Node child, int[][]array, int h, int w, boolean nocopy)
  433. {
  434. calc(child, parent.widget.getS(), parent.widget.getT(), array, h, w, nocopy);
  435. }
  436.  
  437.  
  438. private void calc(Node node, int s, int t, int[][] array, int h, int w, boolean nocopy)
  439. {
  440. if (node == null)
  441. {
  442. return;
  443. }
  444. int ds = node.widget.getS() - s;
  445. int dt = node.widget.getT() - t;
  446. int hh = h - ds;
  447. int ww = w - dt;
  448. int[][] temp;
  449. if (nocopy)
  450. {
  451. temp = array;
  452. }
  453. else
  454. {
  455. temp = new int[hh][ww];
  456. }
  457. int count = 0;
  458. for (int i = 0; i < hh; i++)
  459. {
  460. for (int j = 0; j < ww; j++)
  461. {
  462. for (int dy = 0; dy <= ds; dy++)
  463. {
  464. for (int dx = 0; dx <= dt; dx++)
  465. {
  466. temp[i][j] += array[i + dy][j + dx];
  467. }
  468. }
  469. if (temp[i][j] == 0)
  470. {
  471. count++;
  472. }
  473. }
  474. }
  475. node.widget.setAnswer(count);
  476. nocopy = node.childrenCount() < 2;
  477. calc(node, node.t_child, temp, hh, ww, nocopy);
  478. calc(node, node.s_child, temp, hh, ww, nocopy);
  479. if (node.pre_t_child != null)
  480. {
  481. for (Node p : node.pre_t_child)
  482. {
  483. calc(node, p, temp, hh, ww, nocopy);
  484. }
  485. }
  486. if (node.pre_s_child != null)
  487. {
  488. for (Node p : node.pre_s_child)
  489. {
  490. calc(node, p, temp, hh, ww, nocopy);
  491. }
  492. }
  493. }
  494.  
  495. public void calc(int h, int w, int[][] home)
  496. {
  497. calc(root, 1, 1, home, h, w, false);
  498. }
  499. }
  500.  
  501.  
Success #stdin #stdout 0.07s 380224KB
stdin
5 5
00000
00100
00010
10001
10000
3
2 2
1 1
3 2
stdout
6
20
2