Назад к лучшим решениям Status: AC, problem ZRIS, contest ZEL06. By rem (Renat Mullakhanov), 2006-02-28 17:48:57.
  1.  
  2. #include <map>
  3. #include <set>
  4. #include <cmath>
  5. #include <queue>
  6. #include <vector>
  7. #include <string>
  8. #include <cstdio>
  9. #include <cstdlib>
  10. #include <cstring>
  11. #include <cassert>
  12. #include <numeric>
  13. #include <algorithm>
  14.  
  15. using namespace std;
  16.  
  17. typedef unsigned char uchar;
  18. typedef unsigned int uint;
  19. typedef unsigned short ushort;
  20. typedef long long int64;
  21. typedef unsigned long long uint64;
  22. typedef long double real;
  23. typedef vector<int> vi;
  24. typedef vector<string> vs;
  25.  
  26. template<class T> T sqr(T a){ return a*a; }
  27.  
  28. #define For(i,a,b) for(int i=(a); i<=(b); i++)
  29. #define Rep(i,n) for(int i=0; i<(n); i++)
  30. #define Size(x) (int(x.size()))
  31. #define Ford(i,a,b) for(int i=(a); i>=(b); i--)
  32. #define Repd(i,n) for(int i=(n)-1; i>=0; i--)
  33. #define Fil(a) memset(&a,0,sizeof(a))
  34. #define Filn(a,n) memset(a,0,(n)*sizeof(a[0]))
  35. #define Cpy(a,b) memcpy(&a,&b,sizeof(a))
  36. #define Mp(x,y) make_pair(x,y)
  37. #define All(v) (v).begin(),(v).end()
  38. #define Foreach(it,v) for(typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it)
  39. #define Fordeach(it,v) for(typeof((v).rbegin()) it=(v).rbegin(); it!=(v).rend(); ++it)
  40.  
  41. #ifdef ONLINE_JUDGE
  42. #define SINT64 "%lld"
  43. #else
  44. #define SINT64 "%I64d"
  45. #endif
  46.  
  47. const int DEPTH_LIMIT=100;
  48.  
  49. int n;
  50. int am[1024][1024],amrow[1024],amcol[1024];
  51. vi vi1,vj1,vi2,vj2;
  52.  
  53. inline void addrect(int i1,int j1,int i2,int j2)
  54. {
  55. vi1.push_back(i1);
  56. vj1.push_back(j1);
  57. vi2.push_back(i2);
  58. vj2.push_back(j2);
  59. int n=i2-i1+1;
  60. int m=j2-j1+1;
  61. --am[n][m]; --amrow[n]; --amcol[m];
  62. if(m!=n)
  63. {
  64. --am[m][n]; --amrow[m]; --amcol[n];
  65. }
  66. }
  67.  
  68. const int THRESHOLD=1000;
  69. int dp[THRESHOLD+1];
  70.  
  71. int horiz(int n,int m,bool fill,int si,int sj)
  72. {
  73. if(amrow[n]==0) return 0;
  74. if(m>THRESHOLD)
  75. {
  76. int s=m;
  77. int from=sj;
  78. Ford(i,m,1)
  79. if(i>s) i=s+1;
  80. else if(am[n][i]>0)
  81. {
  82. int k=min(am[n][i],s/i);
  83. if(!fill) s-=k*i;
  84. else
  85. {
  86. while(k--)
  87. {
  88. s-=i;
  89. addrect(si,from,si+n-1,from+i-1);
  90. from+=i;
  91. }
  92. }
  93. }
  94. return m-s;
  95. }
  96. else
  97. {
  98. For(i,0,m) dp[i]=-1;
  99. dp[0]=0;
  100. Ford(i,m,1)
  101. {
  102. if(dp[m]!=-1) break;
  103. Repd(z,am[n][i])
  104. {
  105. bool changes=false;
  106. Ford(j,m,i) if(dp[j]==-1 && dp[j-i]!=-1)
  107. {
  108. changes=true;
  109. dp[j]=i;
  110. }
  111. if(!changes || dp[m]!=-1) break;
  112. }
  113. }
  114. int k=m;
  115. while(dp[k]==-1) --k;
  116. int ret=k;
  117. if(fill)
  118. {
  119. int from=sj;
  120. while(k>0)
  121. {
  122. addrect(si,from,si+n-1,from+dp[k]-1);
  123. from+=dp[k];
  124. k-=dp[k];
  125. }
  126. }
  127. return ret;
  128. }
  129. }
  130.  
  131. int vert(int n,int m,bool fill,int si,int sj)
  132. {
  133. if(amcol[m]==0) return 0;
  134. if(n>THRESHOLD)
  135. {
  136. int s=n;
  137. int from=si;
  138. Ford(i,n,1)
  139. if(i>s) i=s+1;
  140. else if(am[i][m]>0)
  141. {
  142. int k=min(am[i][m],s/i);
  143. if(!fill) s-=k*i;
  144. else
  145. {
  146. while(k--)
  147. {
  148. s-=i;
  149. addrect(from,sj,from+i-1,sj+m-1);
  150. from+=i;
  151. }
  152. }
  153. }
  154. return n-s;
  155. }
  156. else
  157. {
  158. For(i,0,n) dp[i]=-1;
  159. dp[0]=0;
  160. Ford(i,n,1)
  161. {
  162. if(dp[n]!=-1) break;
  163. Repd(z,am[m][i])
  164. {
  165. bool changes=false;
  166. Ford(j,n,i) if(dp[j]==-1 && dp[j-i]!=-1)
  167. {
  168. changes=true;
  169. dp[j]=i;
  170. }
  171. if(!changes || dp[n]!=-1) break;
  172. }
  173. }
  174. int k=n;
  175. while(dp[k]==-1) --k;
  176. int ret=k;
  177. if(fill)
  178. {
  179. int from=si;
  180. while(k>0)
  181. {
  182. addrect(from,sj,from+dp[k]-1,sj+m-1);
  183. from+=dp[k];
  184. k-=dp[k];
  185. }
  186. }
  187. return ret;
  188. }
  189. }
  190.  
  191. void solve(int si,int sj,int n,int m,int depth)
  192. {
  193. //assert(1<=n && n<=1000 && 1<=m && m<=1000);
  194. if(depth>DEPTH_LIMIT)
  195. {
  196. int s1=n*horiz(n,m,false,si,sj);
  197. int s2=m*vert(n,m,false,si,sj);
  198. if(s1>s2) horiz(n,m,true,si,sj);
  199. else vert(n,m,true,si,sj);
  200. return;
  201. }
  202. if(horiz(n,m,false,si,sj)==m)
  203. {
  204. assert(horiz(n,m,true,si,sj)==m);
  205. return;
  206. }
  207. if(vert(n,m,false,si,sj)==n)
  208. {
  209. assert(vert(n,m,true,si,sj)==n);
  210. return;
  211. }
  212. Rep(q,2)
  213. {
  214. if((n>m)^q)
  215. {
  216. int mx,k;
  217. mx=k=0;
  218. Ford(i,n,1)
  219. {
  220. //if(m*i<=mx*k) break;
  221. int cur=horiz(i,m,false,si,sj);
  222. if(cur>mx)
  223. {
  224. mx=cur;
  225. k=i;
  226. if(mx==m) break;
  227. }
  228. }
  229. if(mx>0)
  230. {
  231. assert(horiz(k,m,true,si,sj)==mx);
  232. if(mx<m) solve(si,sj+mx,k,m-mx,depth+1);
  233. if(k<n) solve(si+k,sj,n-k,m,depth+1);
  234. return;
  235. }
  236. }
  237. else
  238. {
  239. int mx,k;
  240. mx=k=0;
  241. Ford(j,m,1)
  242. {
  243. //if(n*j<=mx*k) break;
  244. int cur=vert(n,j,false,si,sj);
  245. if(cur>mx)
  246. {
  247. mx=cur;
  248. k=j;
  249. if(mx==n) break;
  250. }
  251. }
  252. if(mx>0)
  253. {
  254. assert(vert(n,k,true,si,sj)==mx);
  255. if(mx<n) solve(si+mx,sj,n-mx,k,depth+1);
  256. if(k<m) solve(si,sj+k,n,m-k,depth+1);
  257. return;
  258. }
  259. }
  260. }
  261. }
  262.  
  263. void gener(int tests,int n)
  264. {
  265. srand(123);
  266. freopen("input.txt","wt",stdout);
  267. printf("%d\n",tests);
  268. while(tests--)
  269. {
  270. printf("%d\n",n);
  271. int k=rand()%50;
  272. printf("%d\n",k);
  273. while(k--) printf("%d %d %d\n",rand()%n+1,rand()%n+1,rand()%5+1);
  274. }
  275. exit(0);
  276. }
  277.  
  278. bool filled[1024][1024];
  279.  
  280. void check()
  281. {
  282. int cnt=0;
  283. For(i,1,n) For(j,1,n) filled[i][j]=false;
  284. Rep(q,Size(vi1))
  285. {
  286. assert(1<=vi1[q] && vi1[q]<=vi2[q] && vi2[q]<=n);
  287. assert(1<=vj1[q] && vj1[q]<=vj2[q] && vj2[q]<=n);
  288. For(i,vi1[q],vi2[q]) For(j,vj1[q],vj2[q])
  289. {
  290. assert(!filled[i][j]);
  291. filled[i][j]=true;
  292. ++cnt;
  293. }
  294. }
  295. printf("%d of %d\n",cnt,n*n);
  296. }
  297.  
  298. void outtest()
  299. {
  300. printf("n=%d\n",n);
  301. For(i,1,n) For(j,1,i) if(am[i][j]>0)
  302. printf("%d %d %d\n",i,j,am[i][j]);
  303. }
  304.  
  305. int main()
  306. {
  307. //gener(10,1000);
  308.  
  309. #ifndef ONLINE_JUDGE
  310. freopen("input.txt","rt",stdin);
  311. freopen("output.txt","wt",stdout);
  312. #endif
  313.  
  314. int t;
  315. scanf("%d",&t);
  316. while(t--)
  317. {
  318. scanf("%d",&n);
  319. For(i,1,n)
  320. {
  321. Filn(am[i],n+1);
  322. amrow[i]=amcol[i]=0;
  323. }
  324. int k;
  325. scanf("%d",&k);
  326. while(k--)
  327. {
  328. int x,y,z;
  329. scanf("%d%d%d",&x,&y,&z);
  330. //assert(1<=x && x<=n && 1<=y && y<=n);
  331. //assert(z>0 && am[x][y]+z<=1000000000);
  332. am[x][y]+=z;
  333. amrow[x]+=z;
  334. amcol[y]+=z;
  335. if(x!=y)
  336. {
  337. am[y][x]+=z;
  338. amrow[y]+=z;
  339. amcol[x]+=z;
  340. }
  341. }
  342. vi1.clear(); vj1.clear();
  343. vi2.clear(); vj2.clear();
  344. //outtest();
  345. solve(1,1,n,n,1);
  346. printf("%d\n",Size(vi1));
  347. Repd(i,Size(vi1)) printf("%d %d %d %d\n",vi1[i],vj1[i],vi2[i],vj2[i]);
  348. //check();
  349. }
  350.  
  351. exit(0);
  352. }