1 条题解

  • 1
    @ 2026-3-12 20:26:20

    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
    上传者