zoukankan      html  css  js  c++  java
  • BZOJ 3343 教主的魔法

    第一次写分块。黄学长的模板好漂亮。

    由于既要保存原始的位置关系,又要有分块的排序,所以开两个数组。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define maxn 1005000
    using namespace std;
    long long n,q,a[maxn],b[maxn],x,y,z,block,pos[maxn],cnt,add[maxn];
    char type[5];
    void reset(long long x)
    {
        long long l=(x-1)*block+1,r=min(x*block,n);
        for (long long i=l;i<=r;i++)
            b[i]=a[i];
        sort(b+l,b+r+1);
    }
    void modify(long long x,long long y,long long z)
    {
        if (pos[x]==pos[y])
        {
            for (long long i=x;i<=y;i++)
                a[i]+=z;
        }
        else
        {
            for (long long i=x;i<=pos[x]*block;i++)
                a[i]+=z;
            for (long long i=(pos[y]-1)*block+1;i<=y;i++)
                a[i]+=z;
            for (long long i=pos[x]+1;i<=pos[y]-1;i++)
                add[i]+=z;
        }
        reset(pos[x]);reset(pos[y]);
    }
    long long find(long long x,long long r)
    {
        long long left=(x-1)*block+1,right=min(x*block,n),last=right;
        while (left<=right)
        {
            long long mid=(left+right)>>1;
            if (b[mid]<r) left=mid+1;
            else right=mid-1;
        }
        return last-left+1;
    }
    long long ask(long long x,long long y,long long z)
    {
        long long sum=0;
        if (pos[x]==pos[y])
        {
            for (long long i=x;i<=y;i++)
                if (a[i]+add[pos[i]]>=z) sum++;
            return sum;
        }
        else
        {
            for (long long i=x;i<=pos[x]*block;i++)
                if (a[i]+add[pos[i]]>=z) sum++;
            for (long long i=(pos[y]-1)*block+1;i<=y;i++)
                if (a[i]+add[pos[i]]>=z) sum++;
            for (long long i=pos[x]+1;i<=pos[y]-1;i++)
                sum=sum+find(i,z-add[i]);
            return sum;
        }
    }
    int main()
    {
        scanf("%lld%lld",&n,&q);
        block=sqrt(n);
        for (long long i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            if (i%block==0) pos[i]=i/block;
            else pos[i]=i/block+1;
        }
        cnt=pos[n];
        for (long long i=1;i<=cnt;i++)
            reset(i);
        for (long long i=1;i<=q;i++)
        {
            scanf("%s%lld%lld%lld",type,&x,&y,&z);
            if (type[0]=='M') modify(x,y,z);
            else printf("%lld
    ",ask(x,y,z));
        }
        return 0;
    }
  • 相关阅读:
    两个路由器配置静态路由只能单边 ping 通
    CVE202125646:Apache Druid远程命令执行漏洞复现
    批量修改图片的格式
    十大远程控制软件排名
    Splashtop 免费60天 大赠送
    单例设计模式
    蓄水池抽样算法/水塘采样算法
    kafka安装(单机版)
    LeetCode382链表随机节点
    LeetCode398随机数索引
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5315784.html
Copyright © 2011-2022 走看看