关于本题的疑问

P2801 教主的魔法

yinianxingkong @ 2023-09-03 22:25:08

rt,萌新初学分块,做常规的块内二分,但是当块长取sqrt(n)

不能过HACK数据1

当块长取sqrt(n)+1

不能过测试点12

可块长取sqrt(n)+2sqrt(n)-1时,就可以AC

AC1-块长sqrt(n)+2

AC2-块长sqrt(n)-1

想问一下,分块不是就是把n个数据分成m块来“优雅的暴力”吗?那么m取多少不是不影响正确性?

想问一下是分块雀食是有可能被卡还是我的代码锅了?

因为没加代码公开计划,所以放一下代码(以块长sqrt(n-1)为例):

码风过于清奇请见谅

#include<bits/stdc++.h>
using namespace std;
namespace TYX_YNXK{
    //def 1
    #define I register int
    #define ll long long
    #define db double
    #define bl bool
    #define il inline
    #define vd void
    #define max(a,b) (((a)>(b))?(a):(b))
    #define min(a,b) (((a)<(b))?(a):(b))
    il vd swap(ll &a,ll &b){
        a^=b;b^=a;a^=b;
    }
    //def 2
    #define N 1000005
    #define M 1200000
    const ll mod=10000000007;
    //read
    #define c ch=getchar()
    il ll read(){
        ll x(0);bl w(1);char c;
        while(ch<48||ch>57){
            if(ch==45) w=0;
            c;
        }while(ch>47&&ch<58){
            x=(x<<1)+(x<<3)+(ch^48);
            c;
        }
        return w?x:-x;
    }
    #undef c
    int n,m,len,belong[N],cnt;
    ll s[N],sor[N];
    struct node{
        int l,r;
        ll lz;
    }t[N];
    il vd init(){
        len=sqrt(n)-1;
        for(int i=1;i<=n;i++) belong[i]=(i-1)/len+1;
        cnt=belong[n];
        for(int i=1;i<=cnt;i++) t[i].l=(i-1)*len+1,t[i].r=i*len;
        t[cnt].r=n;
        for(int i=1;i<=cnt;i++){
            sort(sor+t[i].l,sor+1+t[i].r);
        }
    }
    il vd pushup(int k){
        for(int i=t[k].l;i<=t[k].r;i++) sor[i]=s[i];
        sort(sor+t[k].l,sor+1+t[k].r);
    }
    il vd update(int l,int r,ll c){
        int ls=belong[l],rs=belong[r];
        if(ls==rs){
            for(int i=l;i<=r;i++) s[i]+=c;
            pushup(ls);
        }else{
            for(int i=l;i<=t[ls].r;i++) s[i]+=c;
            pushup(ls);
            for(int i=t[rs].l;i<=r;i++) s[i]+=c;
            pushup(rs);
            for(int i=ls+1;i<=rs-1;i++) t[i].lz+=c;
        }
    }
    il int Ef(int k,ll c){
        int l=t[k].l,r=t[k].r,ans=-1,mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(sor[mid]+t[k].lz>=c) r=mid-1,ans=mid;
            else l=mid+1;
        }
        if(ans==-1) return 0;
        return t[k].r-ans+1;
    }
    il ll query(int l,int r,ll c){
        ll ans=0;
        int ls=belong[l],rs=belong[r];
        if(ls==rs){
            for(int i=l;i<=r;i++){
                if(s[i]+t[ls].lz>=c) ans++;
            }
            return ans;
        }else{
            for(int i=l;i<=t[ls].r;i++){
                if(s[i]+t[ls].lz>=c) ans++;
            }
            for(int i=t[rs].l;i<=r;i++){
                if(s[i]+t[ls].lz>=c) ans++;
            }
            for(int i=ls+1;i<=rs-1;i++){
                ans+=Ef(i,c);
            }
            return ans;
        }
    }
    signed main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++) s[i]=read(),sor[i]=s[i];
        init();
        for(int i=1;i<=m;i++){
            char opt;
            scanf("%s",&opt);
            int l=read(),r=read();
            ll c=read();
            switch(opt){
                case 'M':{
                    update(l,r,c);
                    break;
                }
                case 'A':{
                    printf("%lld\n",query(l,r,c));
                    break;
                }
            }
        }
        return 0;
    }
}
signed main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    TYX_YNXK::main();
    return 0;
}

以上,第一次求助帖,有什么问题请直接指出(心理接受能力还行),违规紫衫,谢谢qwq

当然如果以前有这类的问题发个链接我直接滚粗


by yinianxingkong @ 2023-09-03 22:26:48

手滑,sqrt(n)-1……


by yinianxingkong @ 2023-09-04 06:52:02

没人吗QWQ


by 彭俊皓123 @ 2023-09-26 17:13:39

同问,sqrt(n) 作为块长时会爆 hack1,改为 sqrt(n)+1 时过了。

插个眼,有了答案踢我一脚。


by 麦子 @ 2023-10-20 22:03:59

同求


by __LYC__qwq @ 2024-02-22 23:20:11

铜球


|