题目传送门(内部题26)


输入格式

第一行有$3$个整数$n,m,q$。
然后有$n$行,每行有一个长度为$m$的字符串,$+$表示正电粒子,$-$表示负电粒子。
然后有$q$行,每行$2$个整数$x,y$,表示将第$x$行第$y$列的正电粒子修改为负电粒子,保证修改前第$x$行第$y$列的粒子带正电。


输出格式

有$q$行,每行一个整数此次修改后所有正电粒子能形成的最大的电场强度。


样例

样例输入:

5 5 5
+-+++
+++++
+++++
+++++
++++-
1 5
2 2
5 3
2 3
1 1

样例输出:

4
3
3
2
2


数据范围与提示

对于所有数据,$1\leqslant n,m\leqslant {10}^3,1\leqslant q\leqslant {10}^3$。


题解

$40\%$算法:

纯暴力,暴力枚举端点,暴力枚举边长,暴力统计。

时间复杂度:$\Theta(n^5)$。

期望得分:$40$分。

实际得分:$40$分。

$70\%$算法:

如果你会二维前缀和,然后你以为你可以拿到$70$分,然后……依然是$40$分。

但是我们发现,假设当前枚举的端点是$(i,j)$,边长为$k$,那么如果当前的正方形不行,那边长更大的肯定也不行;如果行,边长更小的肯定也行,那么我们要找的答案就在这行与不行的分界点上,而这个分界点你可以通过二分来找。

时间复杂度:$\Theta(n^2\log n)$。

期望得分:$40$分。

实际得分:$40$分。

$70\%pro$算法:

题目中只会把正电子变为负电子,所以最大的电场强度一定是单调不递增的。

进而,如果我们现在改变的这个电荷不在最大的正方形内,也就是它的改变对答案并没有影响,那么我们就可以标记它改变了,然后输出上一次的答案。

如果它在最大正方形里,那么暴力再来一遍好啦。

在二分的时候,如果已经不能出现比现在已经计算出来的答案更大的答案,就直接$continue$掉好啦。

由于强大的剪枝,你就可以用这个算法$A$掉这道题了,但是仍能被极端数据卡掉。

时间复杂度:$\Theta(n^2\log n)$。

期望得分:$70$分。

实际得分:$100$分。


代码时刻

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,m,q;
  4. char ch[1001];
  5. int Map[1001][1001],sum[1001][1001];
  6. int maxn,ans=1001;
  7. pair<int,int> pre;
  8. int main()
  9. {
  10. scanf("%d%d%d",&n,&m,&q);
  11. maxn=min(n,m);
  12. for(int i=1;i<=n;i++)
  13. {
  14. scanf("%s",ch+1);
  15. for(int j=1;j<=m;j++)
  16. {
  17. if(ch[j]=='+')Map[i][j]=1;
  18. sum[i][j]=Map[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
  19. }
  20. }
  21. while(q--)
  22. {
  23. int x,y;
  24. scanf("%d%d",&x,&y);
  25. Map[x][y]=0;
  26. if(x<pre.first||y<pre.second||x>pre.first+ans-1||y>pre.second+ans-1)
  27. {
  28. printf("%d\n",ans);
  29. continue;
  30. }
  31. for(int i=1;i<=n;i++)
  32. for(int j=1;j<=m;j++)
  33. sum[i][j]=Map[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
  34. ans=0;
  35. for(int i=1;i<=n;i++)
  36. for(int j=1;j<=m;j++)
  37. {
  38. int lft=1,rht=min(maxn,min(n-i+1,m-j+1)),res=0;
  39. if(rht<=ans)break;
  40. while(lft<=rht)
  41. {
  42. int mid=(lft+rht)>>1;
  43. if(sum[i+mid-1][j+mid-1]-sum[i+mid-1][j-1]-sum[i-1][j+mid-1]+sum[i-1][j-1]==mid*mid){lft=mid+1,res=mid;}
  44. else rht=mid-1;
  45. if(rht<=ans)break;
  46. }
  47. if(res>ans)
  48. {
  49. ans=res;
  50. pre=make_pair(i,j);
  51. }
  52. }
  53. printf("%d\n",ans);
  54. maxn=ans;
  55. }
  56. return 0;
  57. }

rp++

[CSP-S模拟测试]:physics(二维前缀和+二分+剪枝)的更多相关文章

  1. Memento Mori (二维前缀和 + 枚举剪枝)

    枚举指的是枚举矩阵的上下界,然后根据p0, p1, p2的关系去找出另外的中间2个点.然后需要记忆化一些地方防止重复减少时间复杂度.这应该是最关键的一步优化时间,指的就是代码中to数组.然后就是子矩阵 ...

  2. C - Monitor CodeForces - 846D (二维前缀和 + 二分)

    Recently Luba bought a monitor. Monitor is a rectangular matrix of size n × m. But then she started ...

  3. [CSP-S模拟测试]:任(duty)(二维前缀和)

    题目描述 $liu\_runda$退役之后就失去梦想开始咸鱼生活了……$Bilibili$夏日画板活动中,所有人都可以在一块画板上进行像素画创作.$UOJ$群有一群无聊的人决定在画板上创作一个$50\ ...

  4. 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和

    题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...

  5. Nowcoder farm ( 树状数组、二维前缀和、二维偏序 )

    题目链接 分析 : 最简单的想法当然就是去模拟 直接对每个施肥料的操作进行模拟.然后计算贡献 但是这显然会超时.这题需要换一个思维 对于一个土地(也就是二维平面上的一个点)的种类是 T' 如果它被操作 ...

  6. 【AcWing 99】激光炸弹——二维前缀和

    (题面来自AcWing) 一种新型的激光炸弹,可以摧毁一个边长为 R 的正方形内的所有的目标. 现在地图上有 N 个目标,用整数Xi,Yi表示目标在地图上的位置,每个目标都有一个价值Wi. 激光炸弹的 ...

  7. openjudge1768 最大子矩阵[二维前缀和or递推|DP]

    总时间限制:  1000ms 内存限制:  65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...

  8. COGS1752 [BOI2007]摩基亚Mokia(CDQ分治 + 二维前缀和 + 线段树)

    题目这么说的: 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它 ...

  9. poj-3739. Special Squares(二维前缀和)

    题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. ...

随机推荐

  1. Fiddler抓包ios亲测

    1 打开Fiddler设置端口 2 设置可以抓取https选项 3 手机连接WIFI和电脑处于同一局域网并设置代理端口和fiddler中设置一致 4 证书安装手机浏览器输入代理电脑ip及端口如192. ...

  2. LeetCode 337. House Robber III 动态演示

    每个节点是个房间,数值代表钱.小偷偷里面的钱,不能偷连续的房间,至少要隔一个.问最多能偷多少钱 TreeNode* cur mp[{cur, true}]表示以cur为根的树,最多能偷的钱 mp[{c ...

  3. word中迅速将表格一分为二 拆分表格快捷键ctrl+shift+enter 重复上一个命令快捷键f4

    这里说的是将一个表格拆分为两个表格 选择要拆分的行,快捷键ctrl+shift+enter,就拆分为两个表格了,是不是很快! 在多个表格需要拆分的时候,做一次这样的操作,然后不停的移动.F4,就可以了 ...

  4. [Linux] 008 文件处理命令

    1. 文件处理命令:touch 命令名称:touch 命令所在路径:/bin/touch 执行权限:所有用户 语法:touch [文件名] 功能描述:创建空文件 范例: 文件名不包含空格 touch ...

  5. JS事件循环,MACRO TASK,MICRO TASK

    事件循环的基本概念 JS执行的过程中,由JS引擎控制的函数调用栈来控制时间循环 定时器线程,事件触发线程,异步http请求线程控制异步的任务队列 任务分为macro task,micro task 对 ...

  6. 【五一qbxt】day7-2 选择客栈

    停更20天祭qwq(因为去准备推荐生考试了一直在自习qwq) [noip2011选择客栈] 这道题的前置知识是DP,可以参考=>[五一qbxt]day3 动态规划 鬼知道我写的是什么emm 这道 ...

  7. CodeChef 3-Palindromes(Manacher+dp)

    3-Palindromes   Problem code: PALIN3   Submit All Submissions   All submissions for this problem are ...

  8. python 字符编码问题总结

    都是计算机存储是二进制0101之类的数字 最早计算机在美国开始的 所以数字和英文之类的占用八位 2的8次方 256可以存储对于英文和数字戳戳有余  每个国家都有自己的编码 中国 gb2312 gbk ...

  9. python中字典类型的使用

    Python字典类型 字典是一种键值对的集合,键值对之间无序 字典类型的定义 采用{}或者dict()来创建字典对象,键值对之间使用:进行分隔. {<键1>:<值1>, < ...

  10. 四 shell基本命令

    一   内置命令 hlep 命令  帮助 help test help -s printf   显示内置命令的语法格式 echo 用来显示一行文字 echo "hello world&quo ...