首页 > 其他分享 >D. Powerful array

D. Powerful array

时间:2024-05-15 09:44:12浏览次数:14  
标签:querys int Powerful pos queryNode array id block

https://codeforces.com/contest/86/problem/D

题意:n个数,m个查询。每个查询给出一个区间,查询的结果是区间内每个数出现次数的平方*该数的总和。

思路:莫队算法。分块,查询排序,输出。

总结:莫队算法适用于离线的情况,他的原理是将查询按左端点分块,块的大小是数量的开平方。然后对查询进行排序,块不同,按块id排序,在相同块内,按右端点升序排序。这种排序规则可以让右指针只往右边走。这里有一个非常重要的优化,就是在相邻的块内,右指针走到了最右边,此时为了避免右指针需要回溯到最左边,将下一个块按右端点降序排序!这点非常重要。 在这种左右指针的移动规则下,直接暴力查询即可!!太强了。

注意:块所在id,一定是按左端点排序。 相邻的块一定要有个波浪线的右指针移动优化。

摘抄一段介绍过来:
原文链接:https://blog.csdn.net/ACpartner/article/details/75998670
莫队算法主要是利用了曼哈顿距离的长度关系,将每一个询问的坐标抽象为一个点,然后将询问分块,进行排序(分块的原因是使得这些询问坐标的移动的曼哈顿距离达到 最小),排序之后再按照此时的顺序进行左右区间的移动,而在内部的实现的过程就要看各个题目的要求了,所以在这里主要是理解到,莫队算法的核心是:平面上移动曼哈顿距离最小 (利用分块求得平面上曼哈顿距离的最小生成树)+ 离线查询(无法在线查询),在解题的过程中也要想到使得每一次转移计算答案的时间也要是O(1)的,到此,莫队算法也就完成。

int BLOCK_SIZE;
struct queryNode{
    int l, r, id, block_id;
    long long ans;

    queryNode(){}

    queryNode(int l_, int r_, int id_):
        l(l_),
        r(r_),
        id(id_),
        block_id(l / BLOCK_SIZE)
        {}

};

void solve(){
    int n, m;
    cin >> n >> m;

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

    BLOCK_SIZE = sqrt(m);
    vector<queryNode> querys;
    for (int i = 1; i <= m; ++i){
        int l, r;
        cin >> l >> r;
        querys.emplace_back(l, r, i);
    }

    /*
      这个优化至关重要
    */
    sort(querys.begin(), querys.end(), [](const queryNode& a, const queryNode& b){
            return a.block_id != b.block_id ? a.block_id < b.block_id : a.block_id & 1 ? a.r < b.r : a.r > b.r;
         });
    int l = 1, r = 0;
    int s = *max_element(a.begin() + 1, a.end());
    vector<int> cnt(s + 1);
    long long ans = 0;
    auto cal = [&](int pos, int value){
        ans -= 1ll * cnt[pos] * cnt[pos] * pos;
        cnt[pos] += value;
        ans += 1ll * cnt[pos] * cnt[pos] * pos;
    };
    for (auto& q : querys){
        while (l < q.l) cal(a[l], -1), l ++;
        while (l > q.l) cal(a[l - 1],  1), l --;
        while (r > q.r) cal(a[r], -1), r --;
        while (r < q.r) cal(a[r + 1], 1), r++;
        q.ans = ans;
    }
    sort(querys.begin(), querys.end(), [](const queryNode& a, const queryNode& b){
            return a.id < b.id;
        });


    for (const auto& x : querys){
        cout << x.ans << '\n';
    }

}

标签:querys,int,Powerful,pos,queryNode,array,id,block
From: https://www.cnblogs.com/yxcblogs/p/18193114

相关文章

  • CF1965D Missing Subarray Sum题解
    题目链接点击打开链接题目解法感觉一点都不好想\fn因为最后的序列\(a\)是回文的,所以只有以中心点对称的子段和出现次数为奇数,其他都为偶数考虑有没有什么知道所有子段和的做法,可以方便推出缺失一个的答案令\(g_{l,r}\)为\(l\)到\(r\)的子段和知道\(g_{1,n}\)删......
  • [LeetCode] Find the Minimum Cost Array Permutation
    Youaregivenanarray nums whichisa permutation of [0,1,2,...,n-1].The score ofanypermutationof [0,1,2,...,n-1] named perm isdefinedas:score(perm)=|perm[0]-nums[perm[1]]|+|perm[1]-nums[perm[2]]|+...+|perm[n-1]-......
  • array_merge和+的区别
    array_merge()array_merge()将一个或多个数组合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果数组1.字符串键后面的值会覆盖前面的一个值。2.数字键,后面的值将不会覆盖原来的值而是附加到后面(数字键会重新分配,总是变成重零开始)3.如果只给了一个数组并该数组是数......
  • LeetCode 2956. Find Common Elements Between Two Arrays
    原题链接在这里:https://leetcode.com/problems/find-common-elements-between-two-arrays/description/题目:Youaregiventwo 0-indexed integerarrays nums1 and nums2 ofsizes n and m,respectively.Considercalculatingthefollowingvalues:Thenumberof......
  • Find Products of Elements of Big Array
    FindProductsofElementsofBigArrayA powerfularray foraninteger x istheshortestsortedarrayofpowersoftwothatsumupto x.Forexample,thepowerfularrayfor11is [1,2,8].Thearray big_nums iscreatedbyconcatenatingthe powerful......
  • LeetCode 1287. Element Appearing More Than 25% In Sorted Array
    原题链接在这里:https://leetcode.com/problems/element-appearing-more-than-25-in-sorted-array/description/题目:Givenanintegerarray sorted innon-decreasingorder,thereisexactlyoneintegerinthearraythatoccursmorethan25%ofthetime,returnthat......
  • 使用Arrays.asList()的坑
    背景在将数组转为list的时候,一般会使用到Arrays.asList()这个方法,但是在对转化后的list进行add操作的时候出现了java.lang.UnsupportedOperationException的报错原因Arrays.asList()方法只是将数组转换为一个固定长度的列表,它不支持增删操作。研究源码发现,它生成的ArrayLis......
  • 终于明白了 Array.sort(comparator) 的原理
    终于明白了Array.sort(comparator)的原理原文地址:https://www.jameskerr.blog/posts/javascript-sort-comparators/After13yearsofJavaScript,IfinallyhaveawaytorememberhowthecomparatorfunctioninArray.sort()works.使用JavaScript13年之后,我终于有......
  • ArrayList in C#
    https://dotnettutorials.net/lesson/arraylist-collection-csharp/c#中的数组列表是什么?c#中的ArrayList是一个非泛型集合类,它的工作方式类似于数组,但提供了动态调整大小、从集合中间添加和删除元素等功能。c#中的ArrayList可以用来添加未知数据,也就是说,当我们不知道数据的类型......
  • 慎用 Arrays.asList
    Java8提供的Stream流式处理大大减少了集合类各种操作(投影、过滤、转换)的代码量,用起来非常香,所以在实际业务开发中,我们常常会把原始的数组转换为List类数据结构,使得其可以用上Stream流操作。Arrays.asList方法应该是各位最常用的数组一键转换为List的方法了,但这个方法......