.article-info-tag,button{text-transform:uppercase}.day,.postMeta,.postSticky{position:relative}.postTitle a:link,html{-webkit-tap-highlight-color:transparent}#blog-calendar,.code-copay-btn,.code-hljs-len,.hidden{visibility:hidden}#EntryTag,#blogTitle h1{margin-top:20px}#EntryTag a,.postSticky{background:#6fa3ef}#blogTitle h1 a:hover,.dayTitle a,a,a:active,a:link,a:visited{color:#5c8ec6}#calendar table a:hover,#navList a:hover,.postDesc a:hover,a:active,a:hover,a:link,a:visited,button{text-decora…ryTag a:visited{color:#666}#BlogPostCategory a,#EntryTag a{height:20px;line-height:20px;color:#fff!important;padding:3px 5px;border-radius:3px;margin:2px 5px 0;text-decoration:none;font-size:14px}#BlogPostCategory a:hover,#EntryTag a:hover{transition:all .3s linear 0s;opacity:.8}#topics .postDesc{padding-left:0;width:100%;text-align:left;color:#666;margin-top:5px;background:0 0}.feedbackListSubtitle-louzhu:after,.feedbackListSubtitle:after,.feedbackListSubtitle:before{top:11px;right:100%;left:-1

SP18185 GIVEAWAY - Give Away

Description

\(n\) 个数,\(m\) 次操作。

0 l r k 查询区间 \([l,r]\) 大于等于 \(k\) 的元素个数。

1 p k\(a_p\) 修改为 \(k\)

限制: \(1\le n,m\le5\times 10^5\)

Solution

考虑分块,设块长为 $S $,用 vector 来存每个块内的元素,对修改操作暴力重构,在块内排序。时间复杂度 \(\Theta(S\log S)\),对查询操作,零散块暴力查询,整块块内二分查找,时间复杂度 \(\Theta(\frac n S\log {S})\),当 \(S=\sqrt n\) 时有最优复杂度 \(\Theta(m\sqrt n\log\sqrt n)\)(默认 \(n,m\) 同阶)。

Code

/*If you are full of hope,you will be invincible*/
#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>
using ll = long long;
using u64 = unsigned long long;
using u32 = unsigned int;
std::mt19937 hpy(time(nullptr)+(unsigned long long)(new char)+20051107);
namespace STD{
	constexpr int HL=1<<20;
	char buf[HL],*t1=buf,*t2=buf;
	inline char getc(){return t1==t2&&(t2=(t1=buf)+fread(buf,1,HL,stdin),t1==t2)?EOF:*t1++;}
	template <typename Tp>
	inline void read(Tp &x) {
		x = 0;static int f = 1;char ch = getc();
		for(;!isdigit(ch);ch=getc()) if(ch=='-') f = 0;
		for(;isdigit(ch);ch=getc()) x=(x<<3)+(x<<1)+(ch^48);
		x=f?x:-x;
	}
	template <typename Tp,typename ...Rp> inline void read(Tp &x,Rp&... rst) {read(x),read(rst...);}
	char buff[HL],*T=buff;
	void flush(){fwrite(buff,1,T-buff,stdout);T=buff;}
	inline void putc(char ch){if(T==buff+HL)flush();*T++=ch;}
	template<typename Tp> inline void print(Tp x){
	    if(x<0)putc('-'),x=-x;
	    if(!x) return putc('0'),void();
	    static int st[20],tp;while(x)st[++tp]=x%10,x/=10;
	    while(tp)putc(st[tp]^48),--tp;
	}
	template <typename Tp> inline void print(const char &ch,Tp x) {print(x),putc(ch);}  
	template<typename T,typename ...Args> inline void print(const char &ch,T x,Args ...args) {print(ch,x);print(ch,args...);}
    template<typename Tp> inline Tp max(const Tp &a,const Tp &b){return a>b?a:b;}
    template<typename Tp,typename... Rst> Tp max(const Tp &a,const Rst... rst) {return max(a,max(rst...));}
    template<typename Tp> inline Tp min(const Tp &a,const Tp &b){return a<b?a:b;}
    template<typename Tp,typename... Rst> Tp min(const Tp &a,const Rst... rst) {return min(a,min(rst...));}
}  
using STD::read;
using STD::print;
using STD::max;
using STD::min;
constexpr int N = 5e5 + 10,M = sqrt(N) + 10;
int a[N],L[M],R[M],n,m,tot,siz;
std::vector<int> v[M];
inline int pos(const int x) {return (x-1)/siz + 1;}
inline void Init() {
    read(n),siz = sqrt(n),tot = pos(n);
    for(int i = 1;i <= n;++i) read(a[i]);
    for(int i = 1;i <= tot;++i) L[i] = R[i-1] + 1,R[i] = i*siz;R[tot] = n;
    for(int i = 1;i <= tot;++i) {
        for(int j = L[i];j <= R[i];++j) 
            v[i].push_back(a[j]);
        std::sort(v[i].begin(),v[i].end());
    } 
}
inline void modify(const int x,const int k) {
    const int posx = pos(x);
    a[x] = k;
    v[posx].clear();
    for(int i = L[posx];i <= R[posx];++i) v[posx].push_back(a[i]);
    std::sort(v[posx].begin(),v[posx].end());
}
inline int calc(const int l,const int r,const int k) {
    int ans = 0;
    for(int i = l;i <= r;++i) ans += (a[i] >= k);
    return ans; 
}
inline int query(const int l,const int r,const int k) {
    int ans = 0;
    const int posl = pos(l),posr = pos(r);
    if(posl == posr) return calc(l,r,k);
    ans += calc(l,R[posl],k) + calc(L[posr],r,k);
    for(int i = posl + 1;i < posr;++i) {
        ans += v[i].end() - std::lower_bound(v[i].begin(),v[i].end(),k);
    }
    return ans ;
}
int main(int argc,const char **argv) {
    Init();
    read(m);
    while(m--) {
        int opt,x,y,z;
        read(opt,x,y);
        if(opt == 0) read(z),print('\n',query(x,y,z));
        else modify(x,y);
    }
    return STD::flush(),0;
}
posted @ 2021-04-08 19:38  feicheng  阅读(70)  评论(0编辑  收藏  举报