首页 > 其他分享 >89 场双周赛

89 场双周赛

时间:2022-10-17 14:56:23浏览次数:58  
标签:tmp vector nums int 双周 89 ans query

2.二的幂数组中查询范围内的乘积

解法1. 暴力枚举

n最大是1e9,未超出int表示范围,最多有30个2的幂

查询数组最大是1e5

暴力枚举的最差时间复杂度就是\(3e6\),不会超时

时间复杂度

  1. 求2的幂,\(O(\log_2^n)\)
  2. m次查询,每次查询最多花费\(O(\log_2^n)\),总的时间复杂度

\(O(\log_2^n + m * \log_2^n)\) = \(O(m * \log_2^n)\)

class Solution {
public:
    vector<int> productQueries(int n, vector<vector<int>>& queries) {
        vector<int> exp;
        int mod = 1e9 + 7;
        for(int i = 1; i <= n; i *= 2)
            if(i & n) exp.push_back(i);

        vector<int> ans;
        for(auto &query : queries)
        {
            long long res = 1;
            while(query[0] <= query[1])
                res = res * exp[query[0]++] % mod; 
            ans.push_back(res);
        }
        return ans;
    }
};

解法2. 暴力枚举 + 预处理

在解法1的基础上,预处理出所有可能的query,之后再查询时,时间复杂度就是O(1)

解法1已知最多有30个2的幂,query可能的选择有\(30+29+28+....+1 = 30*31/2\)种

时间复杂度

  1. 求2的幂, \(O(\log_2^n)\)
  2. 预处理\(O((\log_2^n * \log_2^n) / 2) = O((\log_2^{2n}) / 2)\)
class Solution {
public:
    vector<int> productQueries(int n, vector<vector<int>>& queries) {
        vector<int> exp;
        int mod = 1e9 + 7;
        vector<vector<int>> pre(31, vector<int>(31));
        for(int i = 1; i <= n; i *= 2)
            if(i & n) exp.push_back(i);

        for(int i = 0; i < exp.size(); i++)
        {
            long long base = 1;
            for(int j = i; j < exp.size(); j++)
            {
                base = base * exp[j] % mod;
                pre[i][j] = base;
            }
        }

        vector<int> ans;
        for(auto &query : queries)
            ans.push_back(pre[query[0]][query[1]]);
        return ans;
    }
};

解法3. 幂次的前缀和

  1. 所有的乘子都是2的幂,所以可以转换成求出2的幂次

    比如例1的第三个查询\(1*2*4*8 = 2^0*2^1*2^2*2^3 = 2^6\)

class Solution {
public:
    vector<int> productQueries(int n, vector<vector<int>> queries) {
        vector<int> exp;
        int mod = 1e9 + 7;
        exp.push_back(0);
        for(int i = 1, base = 0; i <= n; i *= 2)
        {
            if(i & n) exp.push_back(base);
            ++base;
        }

        for(int i = 1; i < exp.size(); i++)
            exp[i] += exp[i - 1];

        vector<int> ans;
        for(auto &query : queries)
        {
            int l = query[0] + 1, r = query[1] + 1;
            long long res = 1, tmp = 2;
            for(int pow = exp[r] - exp[l - 1]; pow > 0; pow >>= 1)
            {
                if(pow & 1)  res = (res * tmp) % mod;
                tmp = tmp * tmp % mod;
            }
            ans.push_back(res);
        }
        return ans;
    }
};

3. 最小化数据中的最大值

解法1. 枚举 + 二分

check函数逻辑

根据给出的target值, 从后向前枚举, 设置num[i] <= target ,最后根据nums[0]判断这个target是否满足check要求

时间复杂度

target最大取值为1e9, 二分check用时O(n), 二分用时\(O(\log_2^{1e9})\),总的时间复杂度是

\(O(30*n)\)

class Solution {
public:
    bool check(vector<int>& nums, int target)
    {
        long long extra = 0;
        for(int i = nums.size() - 1; i >= 1; i--)
            if(extra + nums[i] > target) extra += nums[i] - target;
            else extra = max(0, (int)extra - target - nums[i]);
        return nums[0] + extra <= target;
    }

    int minimizeArrayValue(vector<int>& nums) {
        int l = 0, r = 1e9 + 10, n = nums.size();
        while(l < r)
        {
            int mid = (l + r) >> 1;
            if(check(nums, mid)) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};

解法2 求平均数

首先可以明确, 右边的值可以转移到左边任意位置,

可以将初始的nums想象为拥有一个不同浪高的海, 后边的浪可以向前滚动,显然当浪高不同时,会发生流动,当海浪平静, 即浪高相同时就能得到最小的最大浪高,即最小最大值

因此可以从前向后求每一点的平均值,这里的平均值需要向上取整,求\(val/x\),且向上取整的结果是\(\frac{val+(x-1)}{x}\)

class Solution {
public:
    int minimizeArrayValue(vector<int> nums) {
        int ans = 0;
        long long tmp = 0;
        for(int i = 0; i < nums.size(); i++){
            tmp += nums[i];
            ans = max(ans, (int)((tmp + i)/(i + 1)));
        }
        return ans;
    }
};

2440. 创建价值相同的连通块

https://www.bilibili.com/video/BV1cV4y157BY/?vd_source=016995e9e676ce29a2a00ff61948cbc5

const int N = 1e6 + 10;
int h[N], val[N], ne[N], idx;
class Solution {
public:
    int target = 0;
    vector<int> w;

    void add(int a, int b)
    {
        val[idx] = b, ne[idx] = h[a], h[a] = idx++;
    }

    int dfs(int p, int fa)
    {
        int weight = w[p];
        for(int i = h[p]; i != -1; i = ne[i])
        {
            int j = val[i];
            if(j == fa) continue;
            int tmp;
            if((tmp = dfs(j, p)) == -1)
                return -1;
            weight += tmp;
        }
        if(weight > target) return -1;
        if(weight == target) return 0;
        return weight;
    }

    int componentValue(vector<int> nums, vector<vector<int>> edges) {
        memset(h, -1, sizeof h);
        w = nums;
        for(auto &edge: edges)
        {
            int a = edge[0], b = edge[1];
            add(a, b), add(b, a);
        }
        int total = 0;
        for(auto & num : nums)
            total += num;
        for(int i = 1; i <= total; i++)
            if(total % i == 0)
            {
                target = i;
                if(dfs(0, -1) != -1) return total / i - 1;
            }
        return 0;
    }
};

标签:tmp,vector,nums,int,双周,89,ans,query
From: https://www.cnblogs.com/INnoVationv2/p/16799190.html

相关文章

  • 面试突击89:事务隔离级别和传播机制有什么区别?
    事务隔离级别和事务传播机制都是对事务行为的规范,但二者描述的侧重点却不同。本文这里所说的事务隔离级别和事务传播机制指的是Spring框架中的机制。1、事务隔离级别事务......
  • Apache Commons Text远程代码执行漏洞(CVE-2022-42889)分析
    漏洞介绍根据apache官方给出的说明介绍到ApacheCommonsText执行变量插值,允许动态评估和扩展属性的一款工具包,插值的标准格式是"${prefix:name}",其中"prefix"是用于定位o......
  • T278789 滑冰
    (芭芭拉太可爱了叭......)题目描述在企鹅国,企鹅们是通过滑冰出行的。每次滑冰需要选择一个营地作为起点,一个营地作为终点,然后从营地\(A(a_x,a_y)\)滑到营地\(B(b_x,b_y......
  • 【JS】89-用JavaScript实现的5个常见函数
    前言    在学习 JavaScript,或者前端面试中,有人会问你节流函数、防抖函数、递归函数等,本文分享了5个常见函数,希望对你有所帮助。    在 JavaScript 中有一些问题......
  • AOZ8902CIL 电路保护 TVS DIODE 4CH 二极管特点
    AOZ8902CIL 特点高速数据线静电防护:-IEC61000-4-2,4级(ESD)抗静电试验-±15kV(空气放电)和±8kV(接触放电)-IEC61000-4-5(闪电)5A(8/20μs)-人体模型(HBM)±15kV包......
  • 面试突击89:事务隔离级别和传播机制有什么区别?
    事务隔离级别和事务传播机制都是对事务行为的规范,但二者描述的侧重点却不同。本文这里所说的事务隔离级别和事务传播机制指的是Spring框架中的机制。1、事务隔离级别事......
  • CF896D Nephren Runs a Cinema 题解
    顺手搬一下吧···inluogu和其他题解不太一样的柿子。把0元,50元,100元分别看成\(-1\),\(0\),\(1\),则问题转化成有多少种由\(-1\),\(0\),\(1\),构成的长为\(n\)的序......
  • Luogu P3389【模板】高斯消元法
    题意给定一个线性方程组,对其求解。$1\leqn\leq100,\left|a_i\right|\leq{10}^4,\left|b\right|\leq{10}^4$题解因为之前贺题解的时候没有理解高斯-约......
  • 189. 轮转数组
    189.轮转数组给你一个数组,将数组中的元素向右轮转k 个位置,其中 k 是非负数。 示例1:输入:nums=[1,2,3,4,5,6,7],k=3输出:[5,6,7,1,2,3,4]解释:向右轮......
  • leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal 根据前
    一、题目大意给定两个整数数组,preorder和postorder,其中preorder是一个具有无重复值的二叉树的前序遍历,postorder是同一棵树的后序遍历,重构并返回二叉树。如果存......