• 教主的魔法


    问题:
    教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N
    每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[LR](1≤LRN)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第LR)个英雄的身高)
    CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [LR] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。
    WD巨懒,于是他把这个回答的任务交给了你。
     
    解:
    分块板题
    动态区间第k小数
    复习一下分块
    code:
    //  
    #include<stdio.h>
    #include<bits/stdc++.h>  
    using namespace std;  
    #define maxnn 2000000  
    int n,Q;  
    int laz[maxnn];  
    int a[maxnn];  
    int s;  
    int k1,k2;  
    int B[6000][6000];  
    int cnt[6000];  
    
      inline int read()
        {
            int x=0,f=1;char ch=getchar();
            while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
            while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
            return x*f;
        }
    void modify(int x,int y,int z)  
    {  
         k1=(x-1)/s+1;  
         k2=(y-1)/s+1;  
        if(k1==k2)  
        {  
            for(int i=x;i<=y;i++)  
            {
                a[i]=a[i]+z;
            }
            cnt[k1]=0;
            for(int i=(k1-1)*s+1;i<=k1*s;i++)
            {
                B[k1][cnt[k1]]=a[i];
                cnt[k1]++;
            }
        }  
        else  
        {  
            for(int i=x;i<=k1*s;i++)  
            {
                a[i]=a[i]+z;
            }
            cnt[k1]=0;
            for(int i=(k1-1)*s+1;i<=k1*s;i++)
            {
                B[k1][cnt[k1]]=a[i];
                cnt[k1]++;
            }
            
             for(int i=(k2-1)*s+1;i<=y;i++)  
            {
                a[i]=a[i]+z;
            }
             cnt[k2]=0;
            for(int i=(k2-1)*s+1;i<=k2*s;i++)
            {
                B[k2][cnt[k2]]=a[i];
                cnt[k2]++;
            }
            for(int i=k1+1;i<k2;i++)  
            {  
                laz[i]+=z;   
            }  
        }  
        
            sort(B[k1],B[k1]+cnt[k1]);    
               sort(B[k2],B[k2]+cnt[k2]);  
    }  
    int query(int x,int y,int z)  
    {  
        int k1=(x-1)/s+1;  
        int k2=(y-1)/s+1;  
        int ans=0;  
        if(k1==k2)  
        {  
            for(int i=x;i<=y;i++)  
            {  
                if(a[i]+laz[k1]>=z) ans++;  
            }  
        }  
        else  
        {  
            for(int i=x;i<=k1*s;i++)  
            if(a[i]+laz[k1]>=z) ans++;  
            for(int i=(k2-1)*s+1;i<=y;i++)  
            {  
                if(a[i]+laz[k2]>=z) ans++;  
            }  
                for(int i=k1+1;i<k2;i++)  
            {  
                ans+=(cnt[i]-(lower_bound(B[i],B[i]+cnt[i],z-laz[i])-B[i]));  
            }  
        }  
        return ans;  
    }  
    int main()  
    {  
        char ch;  
        
        n=read();
        Q=read();
        
        int x,y,z;  
        for(int i=1;i<=n;i++)  
        {  
           a[i]=read(); 
        }  
         s=int(sqrt(n));  
        for(int i=1;i<=n;i++)  
        {  
            int k=(i-1)/s+1;  
            B[k][cnt[k]]=a[i]; 
            cnt[k]++;  
        }  
        for(int i=1;i<=s+1;i++)  
        {  
            sort(B[i],B[i]+cnt[i]);  
        }  
        while(Q--)  
        {  
            cin>>ch;  
              
            if(ch=='A')  
            {  
                x=read();y=read();
                z=read();  
                cout<<query(x,y,z)<<endl;  
            }  
            else  
            {  
                
                x=read();y=read();
                z=read();   
                modify(x,y,z);  
            }  
        }  
    }
     
    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    c语言 数组合并
    c++ 静态函数
    c++ 多继承 公有,私有,保护
    c++ 多继承 public
    stat用法:获取文件对应权限的数字
    sublime text3 (Mac) 快捷键
    c++ 多继承
    C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
    更换主机后SSH无法登录的问题
    ssh 连接不同无线网且IP以及用户名都相同
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11370632.html
Copyright © 2020-2023  润新知