数据结构
再智障错误我每天打一个数据结构
第一次线段树
第二次手打堆
第三次左偏树
第四次K-Dtree
第五次虚树
第六次splay
第七次LCT
第八次treap
第九次树套树
第十次就去死吧
最近我在搞什么鬼。
今天T2一个bool变量忘了清零,T3所有变量都忘了清零,帮别人debug也把函数错了;
昨天T1和T3爆空间,前天mod应该是maxnn写成了maxn,debug两小时;
大前天双向边开成了单向。
再前一天把出栈的标记放在了括号外面。
再这样考个铲铲,天天爆零。
第一次:POJ1062昂贵的聘礼单向边开成了双向。洛谷P3373线段树2:
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=1e5+10; long long n,m,mod,v[maxn]; struct Node{ long long l,r,sum,laz[2]; }node[4*maxn]; long long aa;char cc; long long read() { aa=0;cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa; } void ud(int pos) { if(node[pos].l==node[pos].r) { node[pos].laz[0]=1;node[pos].laz[1]=0; return; } if(!node[pos].laz[1]&&node[pos].laz[0]==1) return; int x; if(node[pos].laz[0]!=1) { x=node[pos].laz[0]; node[pos<<1].laz[0]=node[pos<<1].laz[0]*x%mod; node[pos<<1].laz[1]=node[pos<<1].laz[1]*x%mod; node[pos<<1|1].laz[0]=node[pos<<1|1].laz[0]*x%mod; node[pos<<1|1].laz[1]=node[pos<<1|1].laz[1]*x%mod; node[pos<<1].sum=node[pos<<1].sum*x%mod; node[pos<<1|1].sum=node[pos<<1|1].sum*x%mod; } if(node[pos].laz[1]) { x=node[pos].laz[1]; node[pos<<1].laz[1]=(node[pos<<1].laz[1]+x)%mod; node[pos<<1|1].laz[1]=(node[pos<<1|1].laz[1]+x)%mod; node[pos<<1].sum=(node[pos<<1].sum+x*(node[pos<<1].r-node[pos<<1].l+1))%mod; node[pos<<1|1].sum=(node[pos<<1|1].sum+x*(node[pos<<1|1].r-node[pos<<1|1].l+1))%mod; } node[pos].laz[0]=1;node[pos].laz[1]=0; } void bld(int pos,int l,int r) { node[pos].l=l;node[pos].r=r; node[pos].laz[0]=1; if(l==r) { node[pos].sum=v[l]; return; } int mid=(l+r)>>1; bld(pos<<1,l,mid); bld(pos<<1|1,mid+1,r); node[pos].sum=(node[pos<<1].sum+node[pos<<1|1].sum)%mod; } void chge(int pos,int l,int r,int p,long long x) { if(node[pos].l==l&&node[pos].r==r) { if(p) { node[pos].sum=(node[pos].sum+x*(node[pos].r-node[pos].l+1)%mod)%mod; node[pos].laz[1]=(node[pos].laz[1]+x)%mod; } else { node[pos].sum=node[pos].sum*x%mod; node[pos].laz[0]=node[pos].laz[0]*x%mod; node[pos].laz[1]=node[pos].laz[1]*x%mod; } return; } ud(pos); int mid=(node[pos].l+node[pos].r)>>1; if(r<=mid) chge(pos<<1,l,r,p,x); else if(l>mid) chge(pos<<1|1,l,r,p,x); else chge(pos<<1,l,mid,p,x),chge(pos<<1|1,mid+1,r,p,x); node[pos].sum=(node[pos<<1].sum+node[pos<<1|1].sum)%mod; } long long q(int pos,int l,int r) { ud(pos); if(node[pos].l==l&&node[pos].r==r) return node[pos].sum; int mid=(node[pos].l+node[pos].r)>>1; if(r<=mid) return q(pos<<1,l,r); else if(l>mid) return q(pos<<1|1,l,r); else return (q(pos<<1,l,mid)+q(pos<<1|1,mid+1,r))%mod; } int main() { n=read();m=read();mod=read(); for(int i=1;i<=n;++i) v[i]=read()%mod; bld(1,1,n); long long op,x,y,z; for(int i=1;i<=m;++i) { op=read();x=read();y=read(); if(op==1||op==2) { z=read(); chge(1,x,y,op-1,z%mod); } else printf("%lld\n",q(1,x,y)); } return 0; } /* 8 10 571373 5929 7152 8443 6028 8580 5449 8473 4237 2 4 8 4376 1 2 8 9637 2 2 6 7918 2 5 8 5681 3 2 8 1 1 5 6482 3 1 5 1 5 8 8701 2 5 8 7992 2 5 8 7806 */
第二次:bzoj1624 寻宝之路maxm写成maxn。洛谷P3378 堆:
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=1e6+10; int n,d[maxn],tot; int aa,ff;char cc; int read() { aa=0;cc=getchar();ff=1; while(cc<'0'||cc>'9') { if(cc=='-')ff=-1; cc=getchar(); } while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa*ff; } void add(int x) { d[++tot]=x; int pos=tot,fa=pos>>1; while(fa&&x<d[fa]) { swap(d[fa],d[pos]); pos=fa;fa=pos>>1; } } void del() { swap(d[1],d[tot]);d[tot--]=0x3f3f3f3f; int pos=1,son; while((pos<<1)<=tot&&min(d[pos<<1],d[pos<<1|1])<d[pos]) { son=pos<<1; if(d[pos<<1|1]<d[son]) son++; swap(d[pos],d[son]); pos=son; } } int main() { n=read(); memset(d,0x3f3f3f,sizeof(d)); int op,x; for(int i=1;i<=n;++i) { op=read(); if(op==1) { x=read(); add(x); } else if(op==2) printf("%d\n",d[1]); else del(); } return 0; }
第三次:TCPThree_C杯忘开long long。洛谷P3377左偏树(可并堆):
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=1e6+10; int n,m; int fa[maxn],num[maxn],son[maxn][2],len[maxn]; bool ud[maxn]; int aa;char cc; int read() { aa=0;cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa; } int find(int x) { return x==fa[x]? x:fa[x]=find(fa[x]); } int merge(int x,int y) { if(!x||!y) return x+y; if(num[x]>num[y]||(num[x]==num[y]&&x>y)) swap(x,y); son[x][1]=merge(son[x][1],y); fa[son[x][1]]=x; if(len[son[x][1]]>len[son[x][0]]) swap(son[x][0],son[x][1]); len[x]=len[son[x][1]]+1; return x; } void del(int x) { if(!len[x]) { printf("-1\n"); return ; } x=find(x); printf("%d\n",num[x]); fa[son[x][0]]=son[x][0]; fa[son[x][1]]=son[x][1]; fa[x]=merge(son[x][0],son[x][1]); len[x]=0;son[x][0]=son[x][1]=0; ud[x]=1; } int main() { n=read();m=read(); for(int i=1;i<=n;++i) { num[i]=read(); fa[i]=i; len[i]=1; } int op,x,y; for(int i=1;i<=m;++i) { op=read(); if(op==1) { x=read();y=read(); if(!len[x]||!len[y]) continue; x=find(x);y=find(y); if(x==y) continue; merge(x,y); } else { x=read(); del(x); } } return 0; }
附上对拍的rand:
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<ctime> using namespace std; const int n=10,m=10; int main() { srand((unsigned)time(NULL)); printf("%d %d\n",n,m); int x,y; for(int i=1;i<=n;++i) printf("%d ",rand()%n+1); printf("\n"); for(int i=1;i<=m;++i) { x=rand()%n+1;y=rand()%n+1; if(rand()%2) printf("1 %d %d\n",x,y); else printf("2 %d\n",x); } return 0; }
第四次:9.22考试乘号打成加号,K-D tree,bzoj4154:
以每个节点的 DFS 序作为横坐标,深度作为纵坐标,那么就可以把一棵树放在坐标系里。
然后我打了一个诡异的像线段树的K-D tree,就跑得贼快(然而我用了整整一个下午debug)。。。
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=1e5+10,mod=1e9+7; int T,n,c,qaq,fa[maxn];long long ans; int aa;char cc; int read() { aa=0;cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa; } int fir[maxn],to[maxn],nxt[maxn],e=0; void add(int x,int y) { to[++e]=y;nxt[e]=fir[x];fir[x]=e; } int dep[maxn],size[maxn],son[maxn]; void dfs1(int pos) { dep[pos]=dep[fa[pos]]+1; size[pos]=1; int y,z; for(y=fir[pos];y;y=nxt[y]) { dfs1(z=to[y]); size[pos]+=size[z]; if(size[z]>size[son[pos]]) son[pos]=z; } } int id[maxn],end[maxn],tot_id; int pyh[maxn]; void dfs2(int pos) { id[pos]=++tot_id; pyh[tot_id]=pos; if(!son[pos]) {end[pos]=id[pos];return ;} dfs2(son[pos]); int y,z; for(y=fir[pos];y;y=nxt[y]) { if((z=to[y])==son[pos]) continue; dfs2(z); } end[pos]=tot_id; } struct Node{ int l,r,d[2];long long cl; }node[4*maxn]; void bld(int pos,int l,int r) { node[pos].l=l;node[pos].r=r; if(l==r) { node[pos].cl=1; node[pos].d[0]=node[pos].d[1]=dep[pyh[l]]; return ; } int mid=(l+r)>>1; bld(pos<<1,l,mid); bld(pos<<1|1,mid+1,r); node[pos].d[0]=min(node[pos<<1].d[0],node[pos<<1|1].d[0]); node[pos].d[1]=max(node[pos<<1].d[1],node[pos<<1|1].d[1]); } void pd(int pos) { if(!node[pos].cl||node[pos].l==node[pos].r) return; node[pos<<1].cl=node[pos].cl;node[pos<<1|1].cl=node[pos].cl; node[pos].cl=0; } long long q(int pos,int x) { if(node[pos].l==node[pos].r) return node[pos].cl; pd(pos); int mid=(node[pos].l+node[pos].r)>>1; if(x<=mid) return q(pos<<1,x); return q(pos<<1|1,x); } void chge(int pos,int l,int r,int d0,int d1,int cl) { if(node[pos].l==l&&node[pos].r==r) { if(node[pos].d[0]>=d0&&node[pos].d[1]<=d1) node[pos].cl=cl; else if(node[pos].l!=node[pos].r){ pd(pos); int mid=(node[pos].l+node[pos].r)>>1; if(node[pos<<1].d[0]<=d1&&node[pos<<1].d[1]>=d0) chge(pos<<1,l,mid,d0,d1,cl); if(node[pos<<1|1].d[0]<=d1&&node[pos<<1|1].d[1]>=d0) chge(pos<<1|1,mid+1,r,d0,d1,cl); } return; } pd(pos); int mid=(node[pos].l+node[pos].r)>>1; if(r<=mid) chge(pos<<1,l,r,d0,d1,cl); else if(l>mid) chge(pos<<1|1,l,r,d0,d1,cl); else chge(pos<<1,l,mid,d0,d1,cl),chge(pos<<1|1,mid+1,r,d0,d1,cl); } void clear() { memset(fir,0,sizeof(fir)); memset(son,0,sizeof(son)); memset(node,0,sizeof(node)); e=0; tot_id=0; ans=0; } int main() { T=read(); while(T--) { n=read();c=read();qaq=read(); clear(); int a,l; for(int i=2;i<=n;++i) fa[i]=read(),add(fa[i],i); dfs1(1); dfs2(1); bld(1,1,n); for(int i=1;i<=qaq;++i) { a=read();l=read();c=read(); if(!c) (ans+=(long long)i*q(1,id[a]))%=mod; else chge(1,id[a],end[a],dep[a],dep[a]+l,c); } printf("%lld\n",ans); } return 0; } /* 1 10 5 5 1 1 2 3 4 5 4 8 2 1 9 2 6 2 1 5 10 1 2 2 2 7 1 0 */
给出对拍的rand:
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<ctime> using namespace std; const int n=10,c=50,q=5; int main() { srand((unsigned)time(NULL)); cout<<"1\n"; cout<<n<<" "<<c<<" "<<q<<"\n"; cout<<"1 "; int x,y,z; for(int i=3;i<=n;++i) { x=rand()%(i-1)+1; cout<<x<<" "; } cout<<"\n"; for(int i=1;i<=q;++i) { x=rand()%n+1;y=rand()%n+1;z=rand()%(c+1); cout<<x<<" "<<y<<" "<<z<<"\n"; } return 0; }
我觉得这篇博文将是我博客里面最长的一篇
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<set> using namespace std; const int maxn=1e5+10; int n,m;long long ans; bool ins[maxn]; set<int> G; set<int>::iterator it; long long aa;char cc; long long read() { aa=0;cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa; } int fir[maxn],nxt[2*maxn],to[2*maxn],e=0; long long v[2*maxn]; void add(int x,int y,long long z) { to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z; to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=z; } int dep[maxn],size[maxn],son[maxn],fa[maxn]; long long sum[maxn]; void dfs1(int pos,int d) { size[pos]=1;dep[pos]=d; int y,z; for(y=fir[pos];y;y=nxt[y]) { if((z=to[y])==fa[pos]) continue; fa[z]=pos; sum[z]=sum[pos]+v[y]; dfs1(z,d+1); size[pos]+=size[z]; if(size[z]>size[son[pos]]) son[pos]=z; } } int id[maxn],num[maxn],top[maxn],tot_id; void dfs2(int pos,int tp) { id[pos]=++tot_id; num[tot_id]=pos; top[pos]=tp; if(!son[pos]) return; dfs2(son[pos],tp); int y,z; for(y=fir[pos];y;y=nxt[y]) { z=to[y]; if(z==fa[pos]||z==son[pos]) continue; dfs2(z,z); } } int lca(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); return x; } long long f(int x) { int l,r; it=G.find(id[x]); it++; if(it==G.end()) it=G.begin(); l=num[*it]; it=G.find(id[x]); if(it==G.begin()) it=G.end(); it--; r=num[*it]; return 2*(sum[lca(l,x)]+sum[lca(x,r)]-sum[x]-sum[lca(l,r)]); } int main() { n=read();m=read(); int x,y;long long z; for(int i=1;i<n;++i) { x=read();y=read();z=read(); add(x,y,z); } dfs1(1,1);dfs2(1,1); for(int i=1;i<=m;++i) { x=read(); if(ins[x]) {ans+=f(x); G.erase(id[x]);} else {G.insert(id[x]); ans-=f(x);} ins[x]^=1; printf("%lld\n",ans); } return 0; }
天哪,wjx说到第十次要开一个虫洞去FFT,瑟瑟发抖。
第六次:9.29考试没开long long。Splay,bzoj1588:
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=32767+10,INF=1e8; int n,ans,root=0; int aa,ff;char cc; int read() { aa=0;ff=1;cc=getchar(); while(cc<'0'||cc>'9') { if(cc=='-') ff=-1; cc=getchar(); } while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa*ff; } struct Node{ int son[2],fa,num; }node[maxn]; int tot=0; void rotate(int pos) { int x=node[pos].fa,y=node[x].fa; int p=node[x].son[1]==pos,pp=node[y].son[1]==x; node[x].son[p]=node[pos].son[!p]; node[pos].son[!p]=x; node[pos].fa=y;node[x].fa=pos; if(node[x].son[p]) node[node[x].son[p]].fa=x; if(root==x) root=pos; else node[y].son[pp]=pos; } void splay(int pos) { int x=node[pos].fa,y=node[x].fa; while(pos!=root) { x=node[pos].fa,y=node[x].fa; if(x!=root) { if(node[x].son[0]==pos ^ node[y].son[0]==x) rotate(pos); else rotate(x); } rotate(pos); } } int q(int pos,int x) { if(!pos) return INF; int rs=abs(node[pos].num-x); if(!rs) return 0; if(node[pos].num>x) return rs=min(rs,q(node[pos].son[0],x)); else return rs=min(rs,q(node[pos].son[1],x)); } void chge(int& pos,int x,int f) { if(!pos) {pos=tot;node[tot].fa=f;return;} if(x<node[pos].num) chge(node[pos].son[0],x,pos); else chge(node[pos].son[1],x,pos); } void add(int x) { node[++tot].num=x; chge(root,x,0); splay(tot); } int main() { n=read();int x,y=1; for(int i=1;i<=n;++i) { x=read(); if(i!=1) ans+=(y=q(root,x)); else ans+=x; if(y) add(x); } printf("%d",ans); return 0; } /* 5 2 3 3 1 7 */
弱者就是会被欺负呀