1 条题解
-
1
1、本题其实不用二维差分数组,因为如果使用了差分数组,则差分修改子区间后还要还原回原数组,还要再重新求前缀和,然后才能查询。这样时间复杂度就是O(tmn),会超时。 2、只用到了二维前缀和数组,然后注意到每盏灯最多只能减少到 a[i][j]-c,如果目前是a[i][j]-c,则按多一次就回到a[i][j],所以具有周期性,并且每个灯泡都要按下k次,所以每个灯泡的按下次数是相同的,则只用一个变量d来表示每个灯泡最终的所按下次数(因为具有周期性,则最终按下次数为k%(c+1)自行验证)。 3、然后求该子区域内所有灯泡数:cnt=(x2-x1+1)(y2-y1+1)。然后求原子区域内灯泡的总亮度为(二维前缀和查询) sum=(s[x2][y2] - s[x1-1][y2] -s[x2][y1-1] +s[x1-1][y1-1]) 4、因为操作后所有灯泡的总减少亮度 : dcnt 5、则操作后所有灯泡的总亮度为:ans = sum - d*cnt;
#include <bits/stdc++.h> #define int long long using namespace std; const int N=310; int a[N][N]; int s[N][N]; int n,m,c,t; //注意:根据本题意所得,其实不需要用到差分数组 void solve() { cin>>n>>m>>c; //每盏灯最多只能减少到 a[i][j]-c //构建二维前缀和 for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>a[i][j]; s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j]; } } cin>>t; while(t--) { int x1,y1,x2,y2,k; cin>>x1>>y1>>x2>>y2>>k; //每个灯泡都会减少的亮度 int d = k%(c+1); //子区域内的总灯泡数 int cnt = (x2-x1+1)*(y2-y1+1); //原子区域内的所有灯泡总亮度 int sum = (s[x2][y2] - s[x1-1][y2] -s[x2][y1-1] +s[x1-1][y1-1]); //操作后的总亮度 int ans = sum - (cnt * d); cout<<ans<<endl; } } signed main() { solve(); return 0; }
信息
- ID
- 617
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 94
- 已通过
- 29
- 上传者