导航

2025.9.28

Posted on 2025-09-28 20:59  tttfred  阅读(11)  评论(0)    收藏  举报

CF920

A

给你一个矩阵(每条边平行坐标轴)的四个点,求出矩阵的面积
直接输入四个x,y 排序,然后(x[2]-x[1])与(y[2]-y[1])的乘积

B

你可以进行以下三种操作:
把一只猫放进0,该位置变成1
把一只猫拿出来 该位置从0变1
把一只猫换到其他位置
问你初始状态变为终状态的最小操作数

只需用两个计数器,分别计算,s中有1与t不同的个数,和t中有1与s不同的个数,然后取最大值即可

C

一个手机 待机每个时间单位消耗a 关机再开机 开机时消耗b
现在有一个操作序列,在操作序列时刻,必须开机
现在给你剩余电量,问你可不可以完成所有操作
直接贪心模拟 每次取待机时间与开机的较小值,看最后和电量大小关系

D

给你一个大小为n的数列a,再给你一个大小为m的备选数列c,让你求sigma(abs(ai-ci))的最大值
我的做法不知道能不能被证明为正确,反正a升序,c降序,然后每次比较两个数列两个端点的绝对值差值的较大值,加和

F

根号分治
注意到d>sqrt(n)可以直接枚举,主要处理d<=sqrt(n)的部分
采用三维数组前缀和,每行存公差,每列存余数,每层存idx,分别用加权和不加权存(便于查询,比如计算某一段,直接把前面的先删掉,再用不加权的前缀和把多余权值删掉)

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    int tt;
    cin >> tt;
    while (tt--)
    {
        int n, q;
        cin >> n >> q;
        vector<int> p(n + 1, 0);

        for (int i = 1; i <= n; i++)
        {
            cin >> p[i];
        }

        int bound = sqrt(n);
        vector<vector<vector<int>>> presum(bound + 1);
        vector<vector<vector<int>>> presumreal(bound + 1);
        for (int i = 1; i <= bound; i++)
        {
            presum[i].resize(i);
            presumreal[i].resize(i);
        }
        for (int i = 1; i <= bound; i++)
        {
            for (int j = 0; j < i; j++)
            {
                presum[i][j].resize(n / i + 2);
                presumreal[i][j].resize(n / i + 2);
            }
        }
        for (int i = 1; i <= bound; i++)
        {
            for (int j = 0; j < i; j++)
            {
                presum[i][j][0] = 0;
                presumreal[i][j][0] = 0;
            }
            for (int j = 1; j <= n; j++)
            {
                int st = j % i;
                int sk = j / i + (j % i != 0);
                presum[i][st][sk] = presum[i][st][sk - 1] + p[j] * sk;
                presumreal[i][st][sk] = presumreal[i][st][sk - 1] + p[j];
            }
        }
       
        for (int i = 0; i < q; i++)
        {
            int s, d, k;
            cin >> s >> d >> k;
            if (d <= bound)
            {
                int reals = s % d;
                int realbound = s / d + (s % d != 0);
                cout << presum[d][reals][realbound + k - 1] - presum[d][reals][realbound - 1] - (presumreal[d][reals][realbound + k - 1] - presumreal[d][reals][realbound - 1]) * (realbound - 1) << " ";
            }
            else
            {
                int ans = 0;
                for (int j = 0; j < k; j++)
                {
                    ans += p[s + j * d] * (j + 1);
                }
                cout << ans << " ";
            }
        }
        cout << endl;
    }
}