挂分记录
记录各种考场犯浑现象。
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\),没挂分。
本文来自博客园,作者:myee,转载请注明原文链接:https://www.cnblogs.com/myee/p/losing-score.html