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;
    }
  • 相关阅读:
    Notification 通知
    首次在MI5手机上看到APP界面 ~
    Installation falied with message Failed to establish session.
    adb.exe 已停止工作
    内容提供器(Content Provider)
    Android 数据存储
    RecyclerView
    UI设计 四种基本布局
    关于Android教学的思考1
    Android 主要控件
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5315784.html
Copyright © 2011-2022 走看看