半生风雪

代码康复训练

Varuxn·2023-09-12 21:22·54 次阅读

代码康复训练

树状数组区间求和P3374#

Copy
#include<bits/stdc++.h> #define int long long using namespace std; const int N=5e5+10; int n,m; struct BIT { int lim,tre[N]; inline int lowbit(int x){return x&(-x);} inline void insert(int x,int val){for(int i=x;i<=lim;i+=lowbit(i))tre[i]+=val;} inline int query(int x){int temp=0;for(int i=x;i>0;i-=lowbit(i))temp+=tre[i];return temp;} inline int query(int l,int r){return query(r)-query(l-1);} }T; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } #undef int int main() { #define int long long T.lim=n=read(); m=read(); for(int i=1,x;i<=n;i++) x=read(),T.insert(i,x); for(int i=1,opt,x,y;i<=m;i++) { opt=read(); x=read(); y=read(); if(opt==1) T.insert(x,y); else printf("%lld\n",T.query(x,y)); } return 0; }

树状数组区间加P3368#

Copy
#include<bits/stdc++.h> #define int long long using namespace std; const int N=5e5+10; int n,m; struct BIT { int lim,tre[N]; inline int lowbit(int x){return x&(-x);} inline void insert(int x,int val){for(int i=x;i<=lim;i+=lowbit(i))tre[i]+=val;} inline void insert(int l,int r,int val){insert(l,val);insert(r+1,-val);} inline int query(int x){int temp=0;for(int i=x;i>0;i-=lowbit(i))temp+=tre[i];return temp;} }T; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } #undef int int main() { #define int long long T.lim=n=read(); m=read(); for(int i=1,x;i<=n;i++) x=read(),T.insert(i,i,x); for(int i=1,opt,x,y,k;i<=m;i++) { opt=read(); x=read(); if(opt==1) y=read(),k=read(),T.insert(x,y,k); else printf("%lld\n",T.query(x)); } return 0; }

线段树区间加P3372#

Copy
#include<bits/stdc++.h> #define int long long #define f() cout<<"Test"<<endl; #define ls x<<1 #define rs x<<1|1 using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1e5+10; struct BIT { int tre[N],lim; inline int lowbit(int x){return x&(-x);} inline int query(int x){int sum=0;for(int i=x;i;i-=lowbit(i))sum+=tre[i];return sum;} inline void insert(int x,int val){for(int i=x;i<=lim;i+=lowbit(i))tre[i]+=val;} inline int query(int l,int r){return query(r)-query(l-1);} }; struct Segment_Tree { struct Node { int dat,laz; }tre[N<<2]; inline void push_up(int x){tre[x].dat=tre[ls].dat+tre[rs].dat;} inline void push_down(int x,int l,int r) { if(!tre[x].laz) return ; int mid=(l+r)>>1; tre[ls].dat+=tre[x].laz*(mid-l+1); tre[rs].dat+=tre[x].laz*(r-mid); tre[ls].laz+=tre[x].laz; tre[rs].laz+=tre[x].laz; tre[x].laz=0; } inline void insert(int x,int l,int r,int L,int R,int val) { if(L<=l&&r<=R) { tre[x].dat+=val*(r-l+1); tre[x].laz+=val; return ; } int mid=(l+r)>>1; push_down(x,l,r); if(L<=mid) insert(ls,l,mid,L,R,val); if(R>mid) insert(rs,mid+1,r,L,R,val); push_up(x); } inline int query(int x,int l,int r,int L,int R) { if(L<=l&&r<=R) return tre[x].dat; int mid=(l+r)>>1,sum=0; push_down(x,l,r); if(L<=mid) sum+=query(ls,l,mid,L,R); if(R>mid) sum+=query(rs,mid+1,r,L,R); push_up(x); return sum; } }T; int n,m; #undef int int main() { #define int long long n=read(); m=read(); for(int i=1,dat;i<=n;i++) dat=read(),T.insert(1,1,n,i,i,dat); for(int i=1,opt,x,y,k;i<=m;i++) { opt=read(); x=read(); y=read(); if(opt==1) k=read(),T.insert(1,1,n,x,y,k); else printf("%lld\n",T.query(1,1,n,x,y)); } return 0; }

主席树P3834#

Copy
#include<bits/stdc++.h> #define int long long #define f() cout<<"Test"<<endl; #define ls tre[x].l #define rs tre[x].r using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=2e5+10; int n,m,cnt,all,root[N],s[N],lsh[N]; struct Node { int dat,l,r; }tre[N*20]; void push_up(int x){tre[x].dat=tre[ls].dat+tre[rs].dat;} int insert(int pre,int l,int r,int pos) { int mid=(l+r)>>1,x=++all; tre[x]=tre[pre]; if(l==r) return tre[x].dat++,x; if(pos<=mid) ls=insert(tre[pre].l,l,mid,pos); else rs=insert(tre[pre].r,mid+1,r,pos); push_up(x); return x; } int query(int x,int y,int l,int r,int k) { if(l==r) return l; int lsum=tre[tre[y].l].dat-tre[ls].dat,mid=(l+r)>>1; if(lsum>=k) return query(ls,tre[y].l,l,mid,k); return query(rs,tre[y].r,mid+1,r,k-lsum); } #undef int int main() { #define int long long n=read(); m=read(); for(int i=1;i<=n;i++) s[i]=lsh[i]=read(); sort(lsh+1,lsh+n+1); cnt=unique(lsh+1,lsh+n+1)-lsh-1; root[0]=++all; for(int i=1;i<=n;i++) s[i]=lower_bound(lsh+1,lsh+cnt+1,s[i])-lsh, root[i]=insert(root[i-1],1,cnt,s[i]); for(int i=1,l,r,k;i<=m;i++) { l=read(); r=read(); k=read(); printf("%lld\n",lsh[query(root[l-1],root[r],1,cnt,k)]); } return 0; }

KMP#

Copy
#include<bits/stdc++.h> #define int long long #define f() cout<<"Test"<<endl; using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1e6+10; int n,m,nxt[N]; char s1[N],s2[N]; #undef int int main() { #define int long long scanf("%s%s",s1+1,s2+1); n=strlen(s1+1); m=strlen(s2+1); for(int i=2,j=0;i<=m;i++) { while(j&&s2[j+1]!=s2[i]) j=nxt[j]; j+=(s2[j+1]==s2[i]); nxt[i]=j; } for(int i=1,j=0;i<=n;i++) { while(j&&s1[i]!=s2[j+1]) j=nxt[j]; j+=(s2[j+1]==s1[i]); if(j==m) printf("%lld\n",i-m+1); } for(int i=1;i<=m;i++) printf("%lld ",nxt[i]); return 0; }

分块 (P3202 弹飞绵羊)#

Copy
#include<bits/stdc++.h> #define int long long #define f() cout<<"Test"<<endl; using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=2e5+10; int n,cnt,T,pos[N],l[N],r[N],s[N],nxt[N],f[N]; #undef int inline void deal(int x) { for(int i=r[x];i>=l[x];i--) if(i+s[i]>r[x]) f[i]=1,nxt[i]=i+s[i]; else f[i]=f[i+s[i]]+1,nxt[i]=nxt[i+s[i]]; } inline int solve(int x){int ans=0;while(x<=n) ans+=f[x],x=nxt[x]; return ans;} int main() { #define int long long n=read(); for(int i=1;i<=n;i++) s[i]=read(); for(int i=1;i<=sqrt(n);i++) l[i]=(i-1)*sqrt(n)+1,r[i]=i*sqrt(n); if(r[cnt=sqrt(n)]!=n) l[cnt+1]=r[cnt]+1,r[++cnt]=n; for(int i=1;i<=cnt;i++) for(int j=l[i];j<=r[i];j++) pos[j]=i; for(int i=1;i<=cnt;i++) deal(i); T=read(); while(T--) { int opt,p,num; opt=read(); p=read()+1; if(opt==1) printf("%lld\n",solve(p)); else num=read(),s[p]=num,deal(pos[p]); } return 0; }

AC自动机+拓扑优化 LuoguP5357#

Copy
#include<bits/stdc++.h> #define int long long #define ull unsigned long long #define f() cout<<"Test: "<<endl using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=2e6+10,M=2e5+10; int n,cnt=1,du[N],ans[M]; int tot,head[M],nxt[M],ver[M]; char ch[N]; queue<int> q; vector<int> v[N]; void add_edge(int x,int y) { ver[++tot]=y; nxt[tot]=head[x]; head[x]=tot; du[y]++; } struct Trie { struct Node { int son[26],fail,dat; }tre[N]; int New(int &x){if(!x) return x=++cnt; return x;} void insert(char *s,int id) { int len=strlen(s),pos=1; for(int i=0;i<len;i++) pos=New(tre[pos].son[s[i]-'a']); v[pos].push_back(id); } void get_Fail() { for(int i=0;i<26;i++) tre[0].son[i]=1; q.push(1); while(!q.empty()) { int x=q.front(); q.pop(); for(int i=0;i<26;i++) { int fail=tre[x].fail,to=tre[x].son[i]; if(!to) tre[x].son[i]=tre[fail].son[i]; else { tre[to].fail=tre[fail].son[i]; add_edge(to,tre[fail].son[i]); q.push(to); } } } } void topu() { for(int i=1;i<=cnt;i++) if(!du[i]) q.push(i); while(!q.empty()) { int x=q.front(); q.pop(); for(int i=head[x];i;i=nxt[i]) { int to=ver[i]; tre[to].dat+=tre[x].dat; if(!(--du[to])) q.push(to); } } } void query(char *s) { int len=strlen(s),pos=1; for(int i=0;i<len;i++) { pos=tre[pos].son[s[i]-'a']; tre[pos].dat++; } topu(); } }T; #undef int int main() { #define int long long n=read(); for(int i=1;i<=n;i++) scanf("%s",ch),T.insert(ch,i); scanf("%s",ch); T.get_Fail(); T.query(ch); for(int i=1;i<=cnt;i++) for(int j=0;j<v[i].size();j++) ans[v[i][j]]=T.tre[i].dat; for(int i=1;i<=n;i++) printf("%lld\n",ans[i]); return 0; }

普通平衡树P3369#

Splay#

Copy
#include<bits/stdc++.h> #define int long long #define ull unsigned long long #define f() cout<<"Test: "<<endl using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1e5+10; struct Splay { int cnt,root,fa[N],dat[N],rec[N],siz[N],son[N][2]; void clear(int x){fa[x]=dat[x]=rec[x]=siz[x]=son[x][0]=son[x][1]=0;} int get(int x){return son[fa[x]][1]==x;} void push_up(int x) { if(!x) return ; siz[x]=rec[x]; if(son[x][0]) siz[x]+=siz[son[x][0]]; if(son[x][1]) siz[x]+=siz[son[x][1]]; } void connect(int x,int y,int pos) { if(x) fa[x]=y; if(y) son[y][pos]=x; } void rotate(int x) { int f=fa[x],ff=fa[fa[x]],px=get(x),pf=get(f); connect(son[x][px^1],f,px); connect(f,x,px^1); connect(x,ff,pf); push_up(f); push_up(x); } void splay(int x) { for(int f;f=fa[x];rotate(x)) if(fa[f]) rotate(get(x)==get(f)?f:x); root=x; } void insert(int val) { if(!root) { root=++cnt; dat[root]=val; siz[root]=rec[root]=1; son[root][0]=son[root][1]=0; return ; } int x=root,f=0; while(true) { // cout<<"Test\n"; if(dat[x]==val) { // cout<<x<<endl; rec[x]++; push_up(x); push_up(f); splay(x); return ; } f=x; x=son[x][val>dat[x]]; if(x) continue; dat[++cnt]=val; siz[cnt]=rec[cnt]=1; fa[cnt]=f; son[f][val>dat[f]]=cnt; push_up(f); splay(cnt); return ; } } int find(int val)//查排名 { int x=root,temp=0; while(true) { // if(x) cout<<x<<' '<<val<<' '<<dat[x]<<' '<<rec[x]<<endl; if(val<dat[x]){x=son[x][0];continue;} temp+=siz[son[x][0]]; if(val==dat[x]) return splay(x),temp+1; temp+=rec[x]; x=son[x][1]; } } int kth(int rk) { int x=root; while(true) { if(son[x][0]&&rk<=siz[son[x][0]]){x=son[x][0]; continue;} if(son[x][0]) rk-=siz[son[x][0]]; if(rk<=rec[x]) return splay(x),dat[x]; rk-=rec[x]; x=son[x][1]; } } int ask_pre() { int x=son[root][0]; while(son[x][1]) x=son[x][1]; return x; } int ask_suf() { int x=son[root][1]; while(son[x][0]) x=son[x][0]; return x; } void del(int val) { find(val); if(rec[root]>1) return rec[root]--,push_up(root),void(); if(!son[root][0]&&!son[root][1]) return clear(root),root=0,void(); if(!son[root][0]) { int temp=root; fa[root=son[root][1]]=0; clear(temp); return ; } if(!son[root][1]) { int temp=root; fa[root=son[root][0]]=0; clear(temp); return ; } int temp=root,left=ask_pre(); splay(left); connect(son[temp][1],root,1); clear(temp); push_up(root); } }T; int n; #undef int int main() { #define int long long n=read(); for(int i=1,opt,x;i<=n;i++) { opt=read(); x=read(); if(opt==1) T.insert(x); else if(opt==2) T.del(x); else if(opt==3) T.insert(x),printf("%lld\n",T.find(x)),T.del(x); else if(opt==4) printf("%lld\n",T.kth(x)); else if(opt==5) T.insert(x),printf("%lld\n",T.dat[T.ask_pre()]),T.del(x); else T.insert(x),printf("%lld\n",T.dat[T.ask_suf()]),T.del(x); } return 0; }

FHQ-Treap#

Copy
#include<bits/stdc++.h> #define int long long #define ull unsigned long long #define f() cout<<"Test: "<<endl #define ls tre[x].l #define rs tre[x].r using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1e5+10; struct FHQ_Treap { int all,root; struct Node { int l,r,siz,dat,key; }tre[N]; int New(int val) { tre[++all]=(Node){0,0,1,val,rand()}; return all; } void push_up(int x){tre[x].siz=tre[ls].siz+tre[rs].siz+1;} void split(int x,int val,int &u,int &v) { if(!x) return u=v=0,void(); if(tre[x].dat<=val) u=x,split(rs,val,rs,v); else v=x,split(ls,val,u,ls); push_up(x); } int merge(int x,int y)//保证x的值都小于y { if(!x||!y) return x+y; if(tre[x].key>tre[y].key) return tre[x].r=merge(tre[x].r,y),push_up(x),x; return tre[y].l=merge(x,tre[y].l),push_up(y),y; } void insert(int val) { int x=0,y=0; split(root,val,x,y); root=merge(merge(x,New(val)),y); } void del(int val) { int x=0,y=0,z=0; split(root,val,x,z); split(x,val-1,x,y); y=merge(tre[y].l,tre[y].r); root=merge(merge(x,y),z); } int find(int val) { int x=0,y=0; split(root,val-1,x,y); int temp=tre[x].siz+1; root=merge(x,y); return temp; } int kth(int x,int rk) { if(tre[ls].siz+1==rk) return tre[x].dat; if(tre[ls].siz>=rk) return kth(ls,rk); return kth(rs,rk-tre[ls].siz-1); } int ask_pre(int val) { int x=0,y=0; split(root,val-1,x,y); int pos=x; while(tre[pos].r) pos=tre[pos].r; root=merge(x,y); return tre[pos].dat; } int ask_suf(int val) { int x=0,y=0; split(root,val,x,y); int pos=y; while(tre[pos].l) pos=tre[pos].l; root=merge(x,y); return tre[pos].dat; } }T; int n; #undef int int main() { #define int long long srand(time(0)); n=read(); for(int i=1,opt,x;i<=n;i++) { opt=read(); x=read(); if(opt==1) T.insert(x); else if(opt==2) T.del(x); else if(opt==3) printf("%lld\n",T.find(x)); else if(opt==4) printf("%lld\n",T.kth(T.root,x)); else if(opt==5) printf("%lld\n",T.ask_pre(x)); else printf("%lld\n",T.ask_suf(x)); } return 0; }

P3391 文艺平衡树#

FHQ-Treap#

Copy
#include<bits/stdc++.h> #define int long long #define ull unsigned long long #define f() cout<<"Test: "<<endl #define ls tre[x].l #define rs tre[x].r using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1e5+10; struct FHQ_Treap { int all,root; struct Node { int l,r,siz,dat,key,laz; }tre[N]; int New(int val) { tre[++all]=(Node){0,0,1,val,rand(),0}; return all; } void push_up(int x){tre[x].siz=tre[ls].siz+tre[rs].siz+1;} void split(int x,int pos,int &u,int &v) { if(!x) return u=v=0,void(); push_down(x); if(pos<=tre[ls].siz) v=x,split(ls,pos,u,ls); else u=x,split(rs,pos-tre[ls].siz-1,rs,v); push_up(x); } int merge(int x,int y) { if(!x||!y) return x+y; push_down(x); push_down(y); if(tre[x].key>tre[y].key) return tre[x].r=merge(tre[x].r,y),push_up(x),x; return tre[y].l=merge(x,tre[y].l),push_up(y),y; } void push_down(int x) { if(!x||!tre[x].laz) return ; tre[x].laz=0; swap(ls,rs); if(ls) tre[ls].laz^=1; if(rs) tre[rs].laz^=1; } void reverse(int l,int r) { int x=0,y=0,z=0; split(root,r,x,z); split(x,l-1,x,y); tre[y].laz^=1; root=merge(merge(x,y),z); } void print(int x) { if(!x) return ; push_down(x); print(ls); printf("%lld ",tre[x].dat); print(rs); } }T; int n,m; #undef int int main() { #define int long long srand(time(0)); n=read(); m=read(); for(int i=1;i<=n;i++) T.root=T.merge(T.root,T.New(i)); for(int i=1,l,r;i<=m;i++) { l=read(); r=read(); T.reverse(l,r); } T.print(T.root); return 0; }

回滚莫队#

Copy
#include<bits/stdc++.h> #define int long long #define ull unsigned long long #define f() cout<<"Pass"<<endl using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1e5+10; int n,m,r,len,maxn,top,pos[N],s[N],ans[N],li[N],ri[N]; struct Node { int l,r,id; bool friend operator < (Node x,Node y) { if(pos[x.l]==pos[y.l]) return x.r<y.r; return x.l<y.l; } }q[N]; struct node { bool opt; int id,val; }sta[N<<1]; signed main() { n=read(); m=read(); len=sqrt(n); for(int i=1;i<=n;i++) s[i]=read(),pos[i]=i/len+1; for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i; sort(q+1,q+m+1); for(int i=1;i<=m;i++) { if(pos[q[i].l]!=pos[q[i-1].l]) { maxn=0; r=pos[q[i].l]*len; for(int j=1;j<=n;j++) li[j]=ri[j]=0; } while(r<q[i].r) { r++; li[s[r]]=li[s[r]-1]+1; ri[s[r]]=ri[s[r]+1]+1; int temp=li[s[r]]+ri[s[r]]-1; maxn=max(maxn,temp); li[s[r]+ri[s[r]]-1]=temp; ri[s[r]-li[s[r]]+1]=temp; } int rec=maxn; for(int j=q[i].l;j<=min(q[i].r,pos[q[i].l]*len);j++) { li[s[j]]=li[s[j]-1]+1; ri[s[j]]=ri[s[j]+1]+1; sta[++top]=(node){0,s[j]-li[s[j]]+1,ri[s[j]-li[s[j]]+1]}; sta[++top]=(node){1,ri[s[j]]+s[j]-1,li[ri[s[j]]+s[j]-1]}; int temp=li[s[j]]+ri[s[j]]-1; rec=max(rec,temp); li[s[j]+ri[s[j]]-1]=temp; ri[s[j]-li[s[j]]+1]=temp; } while(top) { if(!sta[top].opt) ri[sta[top].id]=sta[top].val; else li[sta[top].id]=sta[top].val; top--; } for(int j=q[i].l;j<=min(q[i].r,pos[q[i].l]*len);j++) li[s[j]]=ri[s[j]]=0; ans[q[i].id]=rec; } for(int i=1;i<=m;i++) printf("%lld\n",ans[i]); return 0; }

笛卡尔树#

Copy
/* 给定一个 1~n的排列 p,构建其笛卡尔树。 即构建一棵二叉树,满足: 每个节点的编号满足二叉搜索树的性质。 节点 i 的权值为 pi,每个节点的权值满足小根堆的性质。 */ void build() { int top=0,pos=0; for(int i=1;i<=n;i++) { pos=top; while(pos&&p[sta[pos]]>p[i]) pos--; if(pos) rs[sta[pos]]=i; if(pos<top) ls[i]=sta[pos+1]; sta[++pos]=i; top=pos; } }

虚树#

Copy
bool comp(int x,int y) { return dfn[x]<dfn[y]; } void build(int x) { if(!top) { sta[++top]=x; return ; } int lca=LCA_ask(x,sta[top]); while(top>1&&dep[lca]<dep[sta[top-1]]) { e2.add(sta[top-1],sta[top]); e2.add(sta[top],sta[top-1]); top--; } if(dep[lca]<dep[sta[top]]) { e2.add(lca,sta[top]); e2.add(sta[top],lca); top--; } if(!top||sta[top]!=lca) sta[++top]=lca; sta[++top]=x; } int main() { while(Q--) { for(int i=1;i<=m;i++) { scanf("%d",&q[i]); vis[q[i]]=true; ans[q[i]]=0; } if(!vis[1]) { flag=true; q[++m]=1; } for(int i=1;i<=m;i++) s[i]=q[i]; sort(s+1,s+m+1,comp); for(int i=1;i<=m;i++) build(s[i]); if(top) while(--top) { e2.add(sta[top],sta[top+1]); e2.add(sta[top+1],sta[top]); } } }

P2479捉迷藏#

KDTree#

Copy
#include<bits/stdc++.h> #define int long long #define ull unsigned long long #define f() cout<<"Test: "<<endl #define ls tre[x].l #define rs tre[x].r using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1e5+10,INF=1e18; bool comp; int maxn[N],minn[N]; struct Node { int d[2],id; bool friend operator < (Node x,Node y) {return x.d[comp]>y.d[comp];} }s[N],temp; int dist(Node x,Node y) { return abs(x.d[0]-y.d[0])+abs(x.d[1]-y.d[1]); } struct K_DTree { int root,all; struct Tree { int l,r,mn[2],mx[2]; Node dat; }tre[N]; void push_up(int x) { for(int i=0;i<=1;i++) { tre[x].mn[i]=tre[x].mx[i]=tre[x].dat.d[i]; if(ls) tre[x].mn[i]=min(tre[x].mn[i],tre[ls].mn[i]), tre[x].mx[i]=max(tre[x].mx[i],tre[ls].mx[i]); if(rs) tre[x].mn[i]=min(tre[x].mn[i],tre[rs].mn[i]), tre[x].mx[i]=max(tre[x].mx[i],tre[rs].mx[i]); } } void build(int &x,int l,int r,int opt) { int mid=(l+r)>>1; comp=opt; nth_element(s+l,s+mid,s+r+1); tre[x=++all].dat=s[mid]; if(l<mid) build(ls,l,mid-1,opt^1); if(r>mid) build(rs,mid+1,r,opt^1); push_up(x); } int KD_max(int x,Node p) { if(!x) return -INF; int sum=0; for(int i=0;i<=1;i++) sum+=max(abs(tre[x].mn[i]-p.d[i]),abs(tre[x].mx[i]-p.d[i])); return sum; } int KD_min(int x,Node p) { if(!x) return INF; int sum=0; for(int i=0;i<=1;i++) sum+=max(0ll,tre[x].mn[i]-p.d[i])+max(0ll,p.d[i]-tre[x].mx[i]); return sum; } void query_max(int x,Node p) { if(!x) return ; int rec=dist(tre[x].dat,p); if(rec>maxn[p.id]) maxn[p.id]=rec,temp=tre[x].dat; int mxl=KD_max(ls,p),mxr=KD_max(rs,p); if(mxl>mxr) { if(mxl>maxn[p.id]) query_max(ls,p); if(mxr>maxn[p.id]) query_max(rs,p); } else { if(mxr>maxn[p.id]) query_max(rs,p); if(mxl>maxn[p.id]) query_max(ls,p); } } void query_min(int x,Node p) { if(!x) return ; int rec=dist(tre[x].dat,p); if(rec<minn[p.id]&&tre[x].dat.id!=p.id) minn[p.id]=rec,temp=tre[x].dat; int mnl=KD_min(ls,p),mnr=KD_min(rs,p); if(mnl<mnr) { if(mnl<minn[p.id]) query_min(ls,p); if(mnr<minn[p.id]) query_min(rs,p); } else { if(mnr<minn[p.id]) query_min(rs,p); if(mnl<minn[p.id]) query_min(ls,p); } } }T; int n,ans=INF; #undef int int main() { #define int long long //实际上就是每一层选择不同维度的排序方式,记录每一个区间内可能存在的最优解 n=read(); for(int i=1;i<=n;i++) s[i].d[0]=read(),s[i].d[1]=read(),s[i].id=i; T.build(T.root,1,n,0); memset(minn,0x7f,sizeof(minn)); for(int i=1;i<=n;i++) { T.query_max(T.root,s[i]); maxn[temp.id]=maxn[s[i].id]; T.query_min(T.root,s[i]); minn[temp.id]=minn[s[i].id]; ans=min(ans,maxn[s[i].id]-minn[s[i].id]); } printf("%lld",ans); return 0; }
posted @   Varuxn  阅读(54)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
目录