ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P2801 教主的魔法

2020-08-30 09:02:56  阅读:279  来源: 互联网

标签:int P2801 魔法 ++ read 教主 1005 sum block


题目描述:这里

思路:

这题似乎是道分块裸题。在查询时,我们可以对每个块进行排序,然后二分查找≥k的元素,输出答案。

不幸的是,这道题有点卡分块。我们可以改变块的大小和加入优化进行卡常。

代码:

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
using namespace std;

template < typename T > void read(T &x)
{
    int f = 1;x = 0;char c = getchar();
    for (;!isdigit(c);c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c);c = getchar()) x = x * 10 + c - '0';
    x *= f;
}

int block, num, l[1005], r[1005], belong[1000005], a[1000005], tag[1005], n, q;

void build()
{
    block = sqrt(n / log2(n));
    num = n / block;
    if(n % block) num++;
    for(int i = 1;i <= num;i++)
    {
        l[i] = (i - 1) * block + 1;
        r[i] = i * block;
    }
    r[num] = n;
    for(int i = 1;i <= n;i++)
        belong[i] = (i - 1) / block;
}

void update(int x, int y, int w)
{
    if(belong[x] == belong[y])
    {
        for(int i = x;i <= y;i++)
            a[i] += w;
    }
    else 
    {
        for(int i = x;i <= r[belong[x]];i++)
            a[i] += w;
        for(int i = l[belong[y]];i <= y;i++)
            a[i] += w;
        for(int i = belong[x] + 1;i <= belong[y] - 1;i++)
            tag[i] += w;
    }
}

int query(int x, int y, int k)
{
    if(belong[x] == belong[y])
    {
        int sum = 0;
        for(int i = x;i <= y;i++)
            if(a[i] + tag[belong[x]] >= k)
                sum++;
        return sum;
    }
    else
    {
        int sum = 0;
        for(int i = x;i <= r[belong[x]];i++)
            if(a[i] + tag[belong[x]] >= k)
                sum++;
        for(int i = l[belong[y]];i <= y;i++)
            if(a[i] + tag[belong[y]] >= k)
                sum++;
        for(int i = belong[x] + 1;i <= belong[y] - 1;i++)
        {
            sort(a + l[i], a + r[i] + 1);
            int lft = l[i], rgh = r[i];
            while(lft <= rgh)
            {
                int mid = (lft + rgh) / 2;
                if(a[mid] + tag[i] >= k)
                    rgh = mid - 1;
                else lft = mid + 1;
            }
            sum += block - lft + 1;
        }
        return sum;
    }
}

int main()
{
    //freopen(".in", "r", stdin);
    //freopen(".out", "w", stdout);
    cin >> n >> q;
    for(int i = 1;i <= n;i++)
        read(a[i]);
    for(int i = 1;i <= q;i++)
    {
        char c;
        cin >> c;
        if(c == 'M')
        {
            int x, y, w;
            read(x);
            read(y);
            read(w);
            update(x, y, w);
        }
        if(c == 'A')
        {
            int x, y, k;
            read(x);
            read(y);
            read(k);
            cout << query(x, y, k) << endl;
        }
    }
    return 0;
}

 

标签:int,P2801,魔法,++,read,教主,1005,sum,block
来源: https://www.cnblogs.com/fy4815/p/13584368.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有