挂分记录

记录各种考场犯浑现象。

20221019

线段树。

正确写法:Seg(uint n):len(n),siz(0),L(NULL),R(NULL),v(0),tag(1){if(n>1)L=new Seg(n>>1),R=new Seg(n-(n>>1));}

错误写法:Seg(uint n):len(n),siz(0),L(NULL),R(NULL),v(0),tag(1){if(n>1)L=new Seg(n>>1),R=new Seg(n>>1);}

结果:\(100\rightarrow20\)

20221021

树上倍增。

没写 a=Fath[i][a]

结果:\(100\rightarrow0\)

20221022

点分治。

错误写法:

voi get(uint p,uint f,uint v){
    cnt[v]++;
    for(auto q:Qid[p])if(p==V[q]){
        for(uint i=0;i<m;i++)Ans[q]+=Qcnt[q][(W[q]+m-i)%m]*cnt[i];
    }
    Qid[p].clear();
    for(auto s:Way[p])if(!Gone[s.first]&&s.first!=f)insert(s.first,p,(v+s.second)%m);
    cnt[v]--;
}

正确写法:

voi get(uint p,uint f,uint v){
    cnt[v]++;
    for(auto q:Qid[p])if(p==V[q]){
        for(uint i=0;i<m;i++)Ans[q]+=Qcnt[q][(W[q]+m-i)%m]*cnt[i];
    }
    Qid[p].clear();
    for(auto s:Way[p])if(!Gone[s.first]&&s.first!=f)get(s.first,p,(v+s.second)%m);
    cnt[v]--;
}

结果:过了小样例,没过大样例,调试了 \(2h\),没挂分。

20221023

伯努利数自然幂和。

数据范围 \(5000\)

错误写法:

modint P[5005],Q[5005],B[5005];
modint Sum(modint n,uint k){
    modint ans,v(1);for(uint i=0;i<=k;i++)ans+=B[k-i]*Q[k-i]*(v*=n)*Q[i+1];
    ans*=P[k];return ans;
}
...
P[0]=1;for(uint i=1;i<=5000;i++)P[i]=P[i-1]*i;
Q[5000]=P[5000].inv();for(uint i=5000;i;i--)Q[i-1]=Q[i]*i;
B[0]=1;for(uint i=1;i<=5000;i++)for(uint j=0;j<i;j++)B[i]-=P[i]*Q[j]*Q[i-j+1]*B[j];

正确写法:

modint P[5005],Q[5005],B[5005];
modint Sum(modint n,uint k){
    modint ans,v(1);for(uint i=0;i<=k;i++)ans+=B[k-i]*Q[k-i]*(v*=n)*Q[i+1];
    ans*=P[k];return ans;
}
...
P[0]=1;for(uint i=1;i<=5001;i++)P[i]=P[i-1]*i;
Q[5001]=P[5001].inv();for(uint i=5001;i;i--)Q[i-1]=Q[i]*i;
B[0]=1;for(uint i=1;i<=5000;i++)for(uint j=0;j<i;j++)B[i]-=P[i]*Q[j]*Q[i-j+1]*B[j];

结果:\(100\rightarrow70\)

20221024

笛卡尔树。

set 暴力构建,复杂度 \(O(n\log n)\)

数据范围 \(10^6\)

结果:\(100\rightarrow85\)

20221027

多数 \(\operatorname{lcm}\) 对大质数取模。

数据范围 \(2n\),筛法只处理到 \(n\)

结果:\(100\rightarrow90\)

20221105

暴力。

并查集合并没有更新父亲。

结果:\(50\rightarrow15\)

20221107

构造题。

没有输出 Yes 就直接构造了。

结果:\(100\rightarrow0\)

20221114

长链剖分。

错误写法:

for(auto s:Son[p])if(s!=Heavy[p])
{
    dfs2(s),tp--;
    for(uint i=0;i<Now[tp].size();i++)
        Now[tp-1][Now[tp-1].size()-i-1]+=Now[tp][i];
}

正确写法:

for(auto s:Son[p])if(s!=Heavy[p]){
    dfs2(s),tp--;
    for(uint i=0;i<Now[tp].size();i++)
        Now[tp-1][Now[tp-1].size()-i-1]+=Now[tp][Now[tp].size()-i-1];
    _min(At[tp-1],At[tp]);
}

结果:\(100\rightarrow25\)

20230131

GBT。

错误写法:

voi dfs1(uint p,uint f){
    Siz[p]=1,Heavy[p]=-1;
    for(auto s:Way[p])if(s!=f){dfs1(s,p),Siz[p]+=Siz[s];if(!~Heavy[p]||Siz[s]>Siz[Heavy[p]])Heavy[p]=s;}
    Siz2[p]=Siz[p];if(~Heavy[p])Siz2[p]-=Siz2[Heavy[p]];
}
voi insert(uint p,modint v,modint w){
    if((++v).empty())Cnt0[p]++;else ALeft[p]*=v;
    B[p]+=w,pushup(p);
}
voi erase(uint p,modint v,modint w){
    if((++v).empty())Cnt0[p]--;else ALeft[p]/=v;
    B[p]-=w,pushup(p);
}
uint get(uint l,uint r,std::vector<uint>&P){
    if(l>=r)return-1;
    uint p=l,v=-1,s=0;for(uint i=l;i<r;i++)s+=Siz2[P[i]];
    for(uint i=l,t=0;i<r;t+=Siz2[i++])if(_min(v,std::max(s-=Siz2[i],t)))p=i;
    if(~(Son[0][P[p]]=get(l,p,P)))Fath[Son[0][P[p]]]=P[p];
    if(~(Son[1][P[p]]=get(p+1,r,P)))Fath[Son[1][P[p]]]=P[p];
    pushup(P[p]);
    return P[p];
}
voi chg(uint p){
    uint s=p;
    while(~s){
        if(~Fath[s]&&ifroot(s))erase(Fath[s],W[s].A02,W[s].A12);
        s=Fath[s];
    }
    V[p]=1;
    while(~p){
        pushup(p);
        if(~Fath[p]&&ifroot(p))insert(Fath[p],W[p].A02,W[p].A12);
        p=Fath[p];
    }
}

正确写法:

voi dfs1(uint p,uint f){
    Siz[p]=1,Heavy[p]=-1;
    for(auto s:Way[p])if(s!=f){dfs1(s,p),Siz[p]+=Siz[s];if(!~Heavy[p]||Siz[s]>Siz[Heavy[p]])Heavy[p]=s;}
    Siz2[p]=Siz[p];if(~Heavy[p])Siz2[p]-=Siz[Heavy[p]];
}
uint get(uint l,uint r,std::vector<uint>&P){
    if(l>=r)return-1;
    uint p=l,v=-1,s=0;for(uint i=l;i<r;i++)s+=Siz2[P[i]];
    for(uint i=l,t=0;i<r;t+=Siz2[P[i++]])if(_min(v,std::max(s-=Siz2[P[i]],t)))p=i;
    if(~(Son[0][P[p]]=get(l,p,P)))Fath[Son[0][P[p]]]=P[p];
    if(~(Son[1][P[p]]=get(p+1,r,P)))Fath[Son[1][P[p]]]=P[p];
    pushup(P[p]);return P[p];
}
uint dfs2(uint p,uint f){
    std::vector<uint>V;
    while(~p){
        V.push_back(p);
        for(auto s:Way[p])if(s!=f&&s!=Heavy[p]){uint r=dfs2(s,p);Fath[r]=p;}
        f=p,p=Heavy[p];
    }
    return get(0,V.size(),V);
}
voi chg(uint p){
    std::vector<uint>U,T;
    uint s=p;
    while(~s){
        if(~Fath[s]&&(Son[0][Fath[s]]!=s&&Son[1][Fath[s]]!=s))U.push_back(s);
        s=Fath[s];
    }
    modvec X,Q={1};
    for(auto s:U){
        B[Fath[s]]-=W[s].A12;
        modint v=W[s].A02+1;
        if(v.empty())Cnt0[Fath[s]]--;
        else T.push_back(Fath[s]),X.push_back(v);
    }
    for(auto&s:X)Q.push_back(Q.back()*s);
    modint g=Q.back().inv();
    for(uint i=T.size()-1;~i;i--)ALeft[T[i]]*=Q[i]*g,g*=X[i];
    V[p]=1;
    while(~p){
        pushup(p);
        if(~Fath[p]&&(Son[0][Fath[p]]!=p&&Son[1][Fath[p]]!=p)){
            B[Fath[p]]+=W[p].A12;
            if(W[p].A02==Mod-1)Cnt0[Fath[p]]++;
            else ALeft[Fath[p]]*=W[p].A02+1;
        }
        p=Fath[p];
    }
}

结果:\(100\rightarrow65\)

20230308

网络流。

没开 long long

结果:\(85\rightarrow60\)

20230313

数据随机的平面最近点对。

只扫了后 \(5\) 个点。

错误写法:

std::pair<uint,uint>get(std::vector<uint>&P){
    uint u=P[0],v=P[1];uint d=dist(u,v);
    if(Spec){
        for(uint i=0;i+1<P.size();i++)if(_min(d,dist(P[i],P[i+1])))u=P[i],v=P[i+1];
    }else{
        for(uint i=0;i<P.size();i++)for(uint j=1;j<=5&&i+j<P.size();j++)
            if(_min(d,dist2(P[i],P[i+j])))u=P[i],v=P[i+j];
    }
    return{u,v};
}

正确写法:

std::pair<uint,uint>get(std::vector<uint>&P){
    uint u=P[0],v=P[1];uint d=dist(u,v);
    if(Spec){
        for(uint i=0;i+1<P.size();i++)if(_min(d,dist(P[i],P[i+1])))u=P[i],v=P[i+1];
    }else{
        for(uint i=0;i<P.size();i++)for(uint j=1;j<=10&&i+j<P.size();j++)
            if(_min(d,dist2(P[i],P[i+j])))u=P[i],v=P[i+j];
    }
    return{u,v};
}

结果:\(100\rightarrow68\)

20230524

dp。

局部变量和全局变量重名。

结果:\(100\rightarrow14\)

20230606

仙人掌。

找环前没有先把和父亲间的权值赋好。

结果:\(100\rightarrow56\)

20230612

计算几何。

认为凸包序就是极角序。

结果:\(100\rightarrow60\)

计算 \(0\sim n-1\)\(\rm popcount\)\(k\) 的数的个数。

错误(高复杂度)写法:

std::map<std::pair<ullt,uint>,ullt>M;
ullt dp(ullt n,uint k)
{
    if(!n)return 0;
    if(!k)return 1;
    if(n==1)return 0;
    if(M.count({n,k}))return M[{n,k}];
    return M[{n,k}]=dp(n/2,k-1)+dp((n+1)/2,k);
}

正确写法:

ullt dp(ullt n,uint k)
{
    uint cnt=__builtin_popcountll(n);
    ullt ans=0;
    while(cnt)
    {
        uint p=__builtin_ctzll(n);n^=1llu<<p;
        if(--cnt<=k)ans+=Binom[p][k-cnt];
    }
    return ans;
}

前一种写法是单次 \(3\log\) 的,完全没得跑。

结果:\(100\rightarrow14\)

20230629

动态网格图线段树分治。

网格图编码得到的哈希值没开 long long

找四联通元素直接 +1 -1 +n -n,不对边界特判。

结果:\(100\rightarrow47\)

20230704

遍历数组。

错误写法:

for(uint i=0;i<P1.size();i++)if(!Op[i])for(uint j=i+1;j<P1.size();j++)
    if(Op[j])ans+=W[i]*get(P[i],P[j]);

正确写法:

for(uint i=0;i<P1.size();i++)if(!Op[P1[i]])for(uint j=i+1;j<P1.size();j++)
    if(Op[P1[j]])ans+=W[P1[i]]*get(P[P1[i]],P[P1[j]]);

结果:没过最后一个大样例,调试了 \(1.5h\),没挂分。

posted @ 2023-03-09 00:00  myee  阅读(116)  评论(3编辑  收藏  举报