再來一波模板整理~
線段樹:
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#define L(x) (x<<1)#define R(x) (x<<1|1)#define sz(x) (tree[x].r-tree[x].l+1)using namespace std;typedef long long LL;const int SZ=200000+10;LL a[SZ];struct SGT{ LL l,r,add,sum;}tree[SZ<<2];void update(LL p){ tree[p].sum=tree[R(p)].sum+tree[L(p)].sum; return;}void spread(LL p){ if(!tree[p].add) return; tree[L(p)].add+=tree[p].add; tree[R(p)].add+=tree[p].add; tree[L(p)].sum+=tree[p].add*sz(L(p)); tree[R(p)].sum+=tree[p].add*sz(R(p)); tree[p].add=0; update(p); return;}void build(LL l,LL r,LL p){ tree[p].l=l;tree[p].r=r; if(l==r) { tree[p].sum=a[l]; return; } LL mid=(tree[p].l+tree[p].r)>>1; build(l,mid,L(p)); build(mid+1,r,R(p)); update(p); return;}void change(LL l,LL r,LL p,LL v){ if(l<=tree[p].l&&tree[p].r<=r) { tree[p].add+=v; tree[p].sum+=v*sz(p); return; } spread(p); LL mid=(tree[p].l+tree[p].r)>>1; if(l<=mid) change(l,r,L(p),v); if(mid<r) change(l,r,R(p),v); update(p); return;}LL ask(LL l,LL r,LL p){ LL ans=0; if(l<=tree[p].l&&tree[p].r<=r) return tree[p].sum; spread(p); LL mid=(tree[p].l+tree[p].r)>>1; if(l<=mid) ans+=ask(l,r,L(p)); if(mid<r) ans+=ask(l,r,R(p)); return ans;}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,n,1); int m; scanf("%d",&m); for(int i=1;i<=m;i++) { int t; scanf("%d",&t); if(t==1) { int l,r,s; scanf("%d%d%d",&l,&r,&s); change(l,r,1,s); } else if(t==2) { int l,r; scanf("%d%d",&l,&r); printf("%lld\n",ask(l,r,1)); } } return 0;}
樹狀數組+差分序列:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define lowbit(x) (x&(-x))using namespace std;const int MAXN=100000+10;int tree[MAXN],c[MAXN],a[MAXN];int n;void add(int x,int y){ while(x<=n) { tree[x]+=y; x+=lowbit(x); }}int sum(int x){ int ans=0; while(x) { ans+=tree[x]; x-=lowbit(x); } return ans;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); c[i]=a[i]-a[i-1]; add(i,c[i]); } int q;scanf("%d",&q); while(q--) { int t,l,r,s; scanf("%d",&t); if(t==1) { scanf("%d%d%d",&l,&r,&s); add(l,s); add(r+1,-s); } if(t==2) { int pos; scanf("%d",&pos); printf("%d\n",sum(pos)); } } return 0;}
並查集:
#include<iostream>#include<cstdio>using namespace std;const int MAXN=5000+50;int fa[MAXN];int find(int x){ if(fa[x]==x) return x; else return fa[x]=find(fa[x]);}void merge(int x,int y){ int fx=find(x); int fy=find(y); fa[fx]=fy;}int main(){ int n,m,q,a,b; scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); merge(a,b); } int x,y; for(int i=1;i<=q;i++) { scanf("%d%d",&x,&y); if(find(x)==find(y)) puts("Yes"); else puts("No"); } return 0;}
單調隊列:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,m;int num[1000000+10];int q[1000000+10],que[1000000+10];void init(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&num[i]);}void up(){ puts(""); int head=1,tail=0; for(int i=1;i<=n;i++) { while(head<=tail&&num[i]>num[q[tail]]) tail--; q[++tail]=i; if(i>=m) { while(head<=tail&&i-m>=q[head]) head++; printf("%d ",num[q[head]]); } }}void down(){ int head=1,tail=0; for(int i=1;i<=n;i++) { while(head<=tail&&num[i]<num[que[tail]]) tail--; que[++tail]=i; if(i>=m) { while(head<=tail&&i-m>=que[head]) head++; printf("%d ",num[que[head]]); } }}void work(){ down(); up();}int main(){ init(); work(); return 0;}