记录编号 361672 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]矩阵乘法 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 15.344 s
提交时间 2017-01-04 20:02:07 内存使用 20.58 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. const int N=510,M=6e5+10;
  5. int n,q,a[N][N],ans[M];
  6. struct opt{
  7. int x1,x2,y1,y2,k,id,tp;
  8. }Q[M];
  9. struct bit{
  10. int a[N];
  11. void add(int p,int d){
  12. for (;p<=n;p+=p&-p) a[p]+=d;
  13. }
  14. int sum(int r){
  15. int ans=0;
  16. for (;r;r-=r&-r) ans+=a[r];
  17. return ans;
  18. }
  19. };
  20. struct RMQ{
  21. bit a[N];
  22. void add(int x,int y,int d){
  23. for (;x<=n;x+=x&-x) a[x].add(y,d);
  24. }
  25. int sum(int x,int y){
  26. int ans=0;
  27. for (;x;x-=x&-x) ans+=a[x].sum(y);
  28. return ans;
  29. }
  30. int sum(int x1,int y1,int x2,int y2){
  31. return sum(x2,y2)-sum(x2,y1-1)-sum(x1-1,y2)+sum(x1-1,y1-1);
  32. }
  33. }T;
  34. bool cmp(const opt &x,const opt &y){
  35. return x.tp==y.tp?x.id<y.id:x.tp<y.tp;
  36. }
  37. void solve(int L,int R,int l,int r){
  38. if (L>R) return;
  39. if (l==r){
  40. for (int i=L;i<=R;i++) ans[Q[i].id]=l;
  41. return;
  42. }
  43. int mid=(l+r)>>1,nl=0;
  44. for (int i=L;i<=R;i++)
  45. if (!Q[i].id){
  46. if (Q[i].k<=mid){
  47. T.add(Q[i].x1,Q[i].y1,1);
  48. Q[i].tp=0;
  49. ++nl;
  50. }
  51. else Q[i].tp=1;
  52. }
  53. else{
  54. int sum=T.sum(Q[i].x1,Q[i].y1,Q[i].x2,Q[i].y2);
  55. if (Q[i].k>sum){
  56. Q[i].k-=sum;
  57. Q[i].tp=1;
  58. }
  59. else Q[i].tp=0,++nl;
  60. }
  61. for (int i=L;i<=R;i++)
  62. if (!Q[i].id&&Q[i].k<=mid)
  63. T.add(Q[i].x1,Q[i].y1,-1);
  64. sort(Q+L,Q+R+1,cmp);
  65. solve(L,L+nl-1,l,mid);
  66. solve(L+nl,R,mid+1,r);
  67. }
  68. int main()
  69. {
  70. freopen("nt2012_mat.in","r",stdin);
  71. freopen("nt2012_mat.out","w",stdout);
  72. scanf("%d%d",&n,&q);
  73. for (int i=1;i<=n;i++)
  74. for (int j=1;j<=n;j++){
  75. scanf("%d",&a[i][j]);
  76. int pos=(i-1)*n+j;
  77. Q[pos].x1=i;Q[pos].y1=j;Q[pos].k=a[i][j];
  78. }
  79. for (int i=n*n+1;i<=n*n+q;i++){
  80. scanf("%d%d%d%d%d",&Q[i].x1,&Q[i].y1,&Q[i].x2,&Q[i].y2,&Q[i].k);
  81. Q[i].id=i-n*n;
  82. }
  83. solve(1,n*n+q,1,1e9);
  84. for (int i=1;i<=q;i++) printf("%d\n",ans[i]);
  85. return 0;
  86. }