模板
1.FFT
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 void fft(int n,Complex *x,int cvs) 2 { 3 for (int i=0,j=0;i<n;i++) 4 { 5 if (i<j) swap(x[i],x[j]); 6 for (int l=(n>>1);(j^=l)<l;l>>=1); 7 } 8 for (int i=2;i<=n;i<<=1) 9 { 10 int l=(i>>1); 11 for (int j=0;j!=n;j+=i) 12 { 13 Complex wn,w; 14 wn=Complex(1,0); 15 w=Complex(cos(2*pi/i*cvs),sin(2*pi/i*cvs)); 16 for (int k=0;k<l;k++) 17 { 18 Complex t=wn*x[j+l+k]; 19 x[j+l+k]=x[j+k]-t; 20 x[j+k]=x[j+k]+t; 21 wn=wn*w; 22 } 23 } 24 } 25 }
2.Splay
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define inf (int)1e9 3 using namespace std; 4 const int N=1e5+100; 5 int n,tot,root,val[N],sz[N],son[N][2]; 6 int fa[N],sf[N],re[N]; 7 int newnode() 8 { 9 return tot++; 10 } 11 void connect(int x,int y,int dir) 12 { 13 son[y][dir]=x; 14 fa[x]=y; 15 sf[x]=dir; 16 } 17 void pushup(int x) 18 { 19 sz[x]=sz[son[x][0]]+sz[son[x][1]]+re[x]; 20 } 21 void clear() 22 { 23 val[0]=son[0][0]=son[0][1]=sz[0]=re[0]=fa[0]=sf[0]=0; 24 } 25 void rotate(int x) 26 { 27 int f,gf,xd,fd,s; 28 f=fa[x];gf=fa[f]; 29 xd=sf[x];fd=sf[f]; 30 s=son[x][xd^1]; 31 connect(x,gf,fd);connect(f,x,xd^1);connect(s,f,xd); 32 clear(); 33 pushup(f);pushup(x); 34 } 35 void splay(int x,int y) 36 { 37 while (fa[x]!=y) 38 { 39 if (fa[fa[x]]==y) 40 rotate(x); 41 else 42 if (sf[fa[x]]==sf[x]) 43 { 44 rotate(fa[x]); 45 rotate(x); 46 } 47 else 48 { 49 rotate(x); 50 rotate(x); 51 } 52 } 53 if (y==0) 54 root=x; 55 } 56 void find(int v) 57 { 58 int cur=root; 59 while (son[cur][v>val[cur]] && val[cur]!=v) 60 cur=son[cur][v>val[cur]]; 61 splay(cur,0); 62 } 63 int per(int v) 64 { 65 find(v); 66 if (val[root]<v) return root; 67 int cur=son[root][0]; 68 while (son[cur][1]) cur=son[cur][1]; 69 return cur; 70 } 71 int suc(int v) 72 { 73 find(v); 74 if (val[root]>v) return root; 75 int cur=son[root][1]; 76 while (son[cur][0]) cur=son[cur][0]; 77 return cur; 78 } 79 void insert(int v) 80 { 81 82 if (root==0) 83 { 84 int x=newnode(); 85 val[x]=v;sz[x]=1; 86 root=x; 87 return; 88 } 89 int cur=root; 90 while (son[cur][v>val[cur]] && val[cur]!=v) 91 cur=son[cur][v>val[cur]]; 92 if (val[cur]==v) 93 { 94 re[cur]++;sz[cur]++; 95 splay(cur,0); 96 return; 97 } 98 int x=newnode(); 99 val[x]=v;re[x]=sz[x]=1; 100 connect(x,cur,v>val[cur]); 101 pushup(cur); 102 splay(x,0); 103 } 104 void del(int v) 105 { 106 int p,s; 107 p=per(v);s=suc(v); 108 splay(p,0); 109 splay(s,p); 110 re[son[s][0]]--;sz[son[s][0]]--; 111 if (re[son[s][0]]==0) 112 son[s][0]=0; 113 pushup(s);pushup(p); 114 } 115 int rk(int v) 116 { 117 find(v); 118 return sz[son[root][0]]; 119 } 120 int kth(int x,int k) 121 { 122 if (k>sz[son[x][0]]+re[x]) 123 return kth(son[x][1],k-sz[son[x][0]]-re[x]); 124 if (k<=sz[son[x][0]]) 125 return kth(son[x][0],k); 126 return x; 127 } 128 int main() 129 { 130 tot=1; 131 insert(inf);insert(-inf); 132 scanf("%d",&n); 133 for (int i=1;i<=n;i++) 134 { 135 int op,x; 136 scanf("%d%d",&op,&x); 137 if (op==1) insert(x); 138 if (op==2) del(x); 139 if (op==3) printf("%d\n",rk(x)); 140 if (op==4) printf("%d\n",val[kth(root,x+1)]); 141 if (op==5) printf("%d\n",val[per(x)]); 142 if (op==6) printf("%d\n",val[suc(x)]); 143 } 144 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define inf (int)1e9 3 using namespace std; 4 const int N=500100; 5 int n,m,tot,root,a[N]; 6 struct node 7 { 8 int sz,val,sum,res,lx,rx,tx,vc; 9 int son[2],fa,sf; 10 }sh[N+100]; 11 queue <int> q; 12 int newnode() 13 { 14 int x; 15 if (tot>=N) 16 { 17 x=q.front(); 18 q.pop(); 19 } 20 else 21 x=tot++; 22 sh[x].sz=sh[x].val=sh[x].sum=sh[x].res=sh[x].lx=sh[x].rx=sh[x].tx=sh[x].vc=0; 23 sh[x].son[0]=sh[x].son[1]=sh[x].sf=sh[x].fa=0; 24 sh[x].vc=inf; 25 return x; 26 } 27 void clear(int x) 28 { 29 q.push(x); 30 if (sh[x].son[0]) clear(sh[x].son[0]); 31 if (sh[x].son[1]) clear(sh[x].son[1]); 32 } 33 void connect(int x,int y,int dir)//x->y 34 { 35 sh[y].son[dir]=x; 36 sh[x].fa=y; 37 sh[x].sf=dir; 38 } 39 void pushdown(int x) 40 { 41 int ls,rs; 42 ls=sh[x].son[0];rs=sh[x].son[1]; 43 if (sh[x].res==1) 44 { 45 if (ls) 46 { 47 sh[sh[ls].son[0]].sf^=1;sh[sh[ls].son[1]].sf^=1; 48 swap(sh[ls].son[0],sh[ls].son[1]); 49 swap(sh[sh[ls].son[0]].lx,sh[sh[ls].son[0]].rx); 50 swap(sh[sh[ls].son[1]].lx,sh[sh[ls].son[1]].rx); 51 sh[ls].res^=1; 52 } 53 if (rs) 54 { 55 sh[sh[rs].son[0]].sf^=1;sh[sh[rs].son[1]].sf^=1; 56 swap(sh[rs].son[0],sh[rs].son[1]); 57 swap(sh[sh[rs].son[0]].lx,sh[sh[rs].son[0]].rx); 58 swap(sh[sh[rs].son[1]].lx,sh[sh[rs].son[1]].rx); 59 sh[rs].res^=1; 60 } 61 sh[x].res=0; 62 } 63 if (sh[x].vc!=inf) 64 { 65 if (ls) 66 { 67 sh[ls].val=sh[ls].vc=sh[x].vc; 68 sh[ls].sum=sh[ls].val*sh[ls].sz; 69 sh[ls].tx=max(sh[ls].val,sh[ls].val*sh[ls].sz); 70 sh[ls].lx=sh[ls].rx=max(0,sh[ls].val*sh[ls].sz); 71 } 72 if (rs) 73 { 74 sh[rs].val=sh[rs].vc=sh[x].vc; 75 sh[rs].sum=sh[rs].val*sh[rs].sz; 76 sh[rs].tx=max(sh[rs].val,sh[rs].val*sh[rs].sz); 77 sh[rs].lx=sh[rs].rx=max(0,sh[rs].val*sh[rs].sz); 78 } 79 sh[x].vc=inf; 80 } 81 } 82 void pushup(int x) 83 { 84 int ls,rs; 85 ls=sh[x].son[0];rs=sh[x].son[1]; 86 sh[x].sz=sh[ls].sz+sh[rs].sz+1; 87 sh[x].sum=sh[ls].sum+sh[rs].sum+sh[x].val; 88 sh[x].lx=max(sh[ls].lx,sh[ls].sum+sh[rs].lx+sh[x].val); 89 sh[x].rx=max(sh[rs].rx,sh[rs].sum+sh[ls].rx+sh[x].val); 90 sh[x].tx=max(sh[ls].tx,max(sh[rs].tx,sh[ls].rx+sh[rs].lx+sh[x].val)); 91 } 92 void rotate(int x) 93 { 94 int fa,gf,son,xd,fd; 95 fa=sh[x].fa;gf=sh[sh[x].fa].fa; 96 xd=sh[x].sf;fd=sh[fa].sf; 97 son=sh[x].son[xd^1]; 98 connect(x,gf,fd);connect(fa,x,xd^1);connect(son,fa,xd); 99 sh[0].fa=sh[0].son[0]=sh[0].son[1]=sh[0].sf=0; 100 pushup(fa);pushup(x); 101 } 102 void splay(int x,int y) 103 { 104 while (sh[x].fa!=y) 105 { 106 if (sh[sh[x].fa].fa==y) 107 rotate(x); 108 else 109 if (sh[x].sf==sh[sh[x].fa].sf) 110 { 111 rotate(sh[x].fa); 112 rotate(x); 113 } 114 else 115 { 116 rotate(x); 117 rotate(x); 118 } 119 } 120 if (y==0) 121 root=x; 122 } 123 int find(int x,int k) 124 { 125 pushdown(x); 126 if (k>sh[sh[x].son[0]].sz+1) 127 return find(sh[x].son[1],k-sh[sh[x].son[0]].sz-1); 128 if (k<=sh[sh[x].son[0]].sz) 129 return find(sh[x].son[0],k); 130 return x; 131 } 132 int build(int l,int r,int father,int dir) 133 { 134 int mid=(l+r)>>1; 135 int x=newnode(); 136 sh[x].val=a[mid]; 137 sh[x].fa=father;sh[x].sf=dir; 138 if (l==r) 139 { 140 sh[x].sz=1; 141 sh[x].sum=sh[x].tx=a[mid]; 142 sh[x].lx=sh[x].rx=max(0,a[mid]); 143 return x; 144 } 145 if (l<=mid-1) 146 sh[x].son[0]=build(l,mid-1,x,0); 147 if (r>=mid+1) 148 sh[x].son[1]=build(mid+1,r,x,1); 149 pushup(x); 150 return x; 151 } 152 int split(int l,int r) 153 { 154 int per,suc; 155 per=find(root,l);suc=find(root,r+2); 156 splay(per,0); 157 splay(suc,per); 158 return sh[suc].son[0]; 159 } 160 int main() 161 { 162 scanf("%d%d",&n,&m); 163 for (int i=1;i<=n;i++) 164 scanf("%d",&a[i]); 165 tot=1;sh[0].tx=a[0]=a[n+1]=-inf; 166 root=build(0,n+1,0,0); 167 while (m--) 168 { 169 char ch[20]; 170 scanf("%s",ch); 171 if (ch[0]=='I') 172 { 173 int pos,tot; 174 scanf("%d%d",&pos,&tot); 175 for (int i=1;i<=tot;i++) 176 scanf("%d",&a[i]); 177 int x=build(1,tot,0,0); 178 int A,B; 179 A=find(root,pos+1);B=find(root,pos+2); 180 splay(A,0);splay(B,A); 181 connect(x,B,0); 182 pushup(B);pushup(A); 183 } 184 if (ch[0]=='D') 185 { 186 int pos,tot; 187 scanf("%d%d",&pos,&tot); 188 int per,suc; 189 per=find(root,pos);suc=find(root,pos+tot+1); 190 splay(per,0); 191 splay(suc,per); 192 clear(sh[suc].son[0]); 193 sh[suc].son[0]=0; 194 pushup(suc);pushup(per); 195 } 196 if (ch[0]=='M' && ch[2]=='K') 197 { 198 int pos,tot,c; 199 scanf("%d%d%d",&pos,&tot,&c); 200 int x=split(pos,pos+tot-1); 201 sh[x].val=sh[x].vc=c; 202 sh[x].sum=c*sh[x].sz; 203 sh[x].tx=max(sh[x].val,c*sh[x].sz); 204 sh[x].lx=sh[x].rx=max(0,c*sh[x].sz); 205 pushup(sh[x].fa);pushup(sh[sh[x].fa].fa); 206 } 207 if (ch[0]=='R') 208 { 209 int pos,tot; 210 scanf("%d%d",&pos,&tot); 211 int x=split(pos,pos+tot-1); 212 sh[x].res^=1; 213 int ls,rs; 214 ls=sh[x].son[0];rs=sh[x].son[1]; 215 sh[ls].sf^=1;sh[rs].sf^=1; 216 swap(sh[x].son[0],sh[x].son[1]); 217 swap(sh[ls].lx,sh[ls].rx); 218 swap(sh[rs].lx,sh[rs].rx); 219 pushup(x);pushup(sh[x].fa);pushup(sh[sh[x].fa].fa); 220 } 221 if (ch[0]=='G') 222 { 223 int pos,tot; 224 scanf("%d%d",&pos,&tot); 225 int x=split(pos,pos+tot-1); 226 printf("%d\n",sh[x].sum); 227 } 228 if (ch[0]=='M' && ch[2]=='X') 229 { 230 printf("%d\n",sh[root].tx); 231 } 232 } 233 }
3.可持久化线段树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=2*1e5+100; 4 int n,m,a[N],b[N],tr[N]; 5 int root[N],cnt; 6 struct node 7 { 8 int ls,rs,sz; 9 }sh[N*40]; 10 int ask(int a) 11 { 12 int pos; 13 pos=lower_bound(b+1,b+1+n,a)-b; 14 return pos; 15 } 16 void pushup(int x) 17 { 18 int ls,rs; 19 ls=sh[x].ls;rs=sh[x].rs; 20 sh[x].sz=sh[ls].sz+sh[rs].sz; 21 } 22 int build(int &x,int l,int r) 23 { 24 if (!x) x=++cnt; 25 if (l==r) return x; 26 int mid=(l+r)>>1; 27 sh[x].ls=build(sh[x].ls,l,mid); 28 sh[x].rs=build(sh[x].rs,mid+1,r); 29 pushup(x); 30 return x; 31 } 32 int change(int x,int l,int r,int wh) 33 { 34 int p=++cnt; 35 sh[p]=sh[x]; 36 if (l==r) 37 { 38 sh[p].sz++; 39 return p; 40 } 41 int mid=(l+r)>>1; 42 if (wh<=mid) sh[p].ls=change(sh[x].ls,l,mid,wh); 43 else sh[p].rs=change(sh[x].rs,mid+1,r,wh); 44 pushup(p); 45 return p; 46 } 47 int query(int lx,int rx,int l,int r,int k) 48 { 49 if (l==r) return l; 50 int lz,mid; 51 mid=(l+r)>>1; 52 lz=sh[sh[rx].ls].sz-sh[sh[lx].ls].sz; 53 if (k<=lz) return query(sh[lx].ls,sh[rx].ls,l,mid,k); 54 else return query(sh[lx].rs,sh[rx].rs,mid+1,r,k-lz); 55 } 56 int main() 57 { 58 scanf("%d%d",&n,&m); 59 for (int i=1;i<=n;i++) 60 scanf("%d",&a[i]); 61 for (int i=1;i<=n;i++) b[i]=a[i]; 62 sort(b+1,b+1+n); 63 for (int i=1;i<=n;i++) 64 { 65 int pos=lower_bound(b+1,b+1+n,a[i])-b; 66 tr[pos]=a[i]; 67 a[i]=pos; 68 } 69 root[0]=build(root[0],1,n); 70 for (int i=1;i<=n;i++) 71 root[i]=change(root[i-1],1,n,a[i]); 72 while (m--) 73 { 74 int l,r,k; 75 scanf("%d%d%d",&l,&r,&k); 76 printf("%d\n",tr[query(root[l-1],root[r],1,n,k)]); 77 } 78 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+100;; 4 int n,m,root[N],a[N]; 5 int cnt; 6 struct node 7 { 8 int ls,rs,val; 9 }sh[N*40]; 10 int build(int &x,int l,int r) 11 { 12 if (!x) x=++cnt; 13 if (l==r) 14 { 15 sh[x].val=a[l]; 16 return x; 17 } 18 int mid=(l+r)>>1; 19 sh[x].ls=build(sh[x].ls,l,mid); 20 sh[x].rs=build(sh[x].rs,mid+1,r); 21 return x; 22 } 23 int change(int x,int l,int r,int wh,int v) 24 { 25 int p=++cnt; 26 sh[p]=sh[x]; 27 if (l==r) 28 { 29 sh[p].val=v; 30 return p; 31 } 32 int mid=(l+r)>>1; 33 if (wh<=mid) sh[p].ls=change(sh[x].ls,l,mid,wh,v); 34 else sh[p].rs=change(sh[x].rs,mid+1,r,wh,v); 35 return p; 36 } 37 int query(int x,int l,int r,int wh) 38 { 39 if (l==r) return sh[x].val; 40 int mid=(l+r)>>1; 41 if (wh<=mid) return query(sh[x].ls,l,mid,wh); 42 else return query(sh[x].rs,mid+1,r,wh); 43 } 44 int main() 45 { 46 scanf("%d%d",&n,&m); 47 for (int i=1;i<=n;i++) 48 scanf("%d",&a[i]); 49 root[0]=build(root[0],1,n); 50 for (int i=1;i<=m;i++) 51 { 52 int ver,op,loc; 53 scanf("%d%d%d",&ver,&op,&loc); 54 if (op==1) 55 { 56 int v; 57 scanf("%d",&v); 58 root[i]=change(root[ver],1,n,loc,v); 59 } 60 if (op==2) 61 { 62 root[i]=root[ver]; 63 printf("%d\n",query(root[ver],1,n,loc)); 64 } 65 } 66 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+100,M=2*1e5+100; 4 int n,m,fa[N],root[M],cnt; 5 struct node 6 { 7 int ls,rs,val,deep; 8 }sh[N*40]; 9 int build(int &x,int l,int r) 10 { 11 if (!x) x=++cnt; 12 if (l==r) 13 { 14 sh[x].val=fa[l]; 15 return x; 16 } 17 int mid=(l+r)>>1; 18 sh[x].ls=build(sh[x].ls,l,mid); 19 sh[x].rs=build(sh[x].rs,mid+1,r); 20 return x; 21 } 22 int change(int x,int l,int r,int wh,int v) 23 { 24 int p=++cnt; 25 sh[p]=sh[x]; 26 if (l==r) 27 { 28 sh[p].val=v; 29 return p; 30 } 31 int mid=(l+r)>>1; 32 if (wh<=mid) sh[p].ls=change(sh[x].ls,l,mid,wh,v); 33 else sh[p].rs=change(sh[x].rs,mid+1,r,wh,v); 34 return p; 35 } 36 void change_depth(int x,int l,int r,int wh) 37 { 38 if (l==r) 39 { 40 sh[x].deep++; 41 return; 42 } 43 int mid=(l+r)>>1; 44 if (wh<=mid) change_depth(sh[x].ls,l,mid,wh); 45 else change_depth(sh[x].rs,mid+1,r,wh); 46 } 47 int query(int x,int l,int r,int wh,int kind) 48 { 49 if (l==r) return (kind==1)?sh[x].val:sh[x].deep; 50 int mid=(l+r)>>1; 51 if (wh<=mid) return query(sh[x].ls,l,mid,wh,kind); 52 else return query(sh[x].rs,mid+1,r,wh,kind); 53 } 54 int find(int x,int &root) 55 { 56 int father=query(root,1,n,x,1); 57 if (x==father) return x; 58 return find(father,root); 59 } 60 int main() 61 { 62 scanf("%d%d",&n,&m); 63 for (int i=1;i<=n;i++) fa[i]=i; 64 root[0]=build(root[0],1,n); 65 for (int i=1;i<=m;i++) 66 { 67 int op; 68 scanf("%d",&op); 69 if (op==1) 70 { 71 int a,b,Fa,Fb,da,db; 72 scanf("%d%d",&a,&b); 73 root[i]=root[i-1]; 74 Fa=find(a,root[i]);Fb=find(b,root[i]); 75 da=query(root[i],1,n,Fa,0);db=query(root[i],1,n,Fb,0); 76 if (Fa==Fb) continue; 77 if (da>db) swap(Fa,Fb); 78 root[i]=change(root[i],1,n,Fa,Fb); 79 change_depth(root[i],1,n,Fb); 80 } 81 if (op==2) 82 { 83 int k; 84 scanf("%d",&k); 85 root[i]=root[k]; 86 } 87 if (op==3) 88 { 89 int a,b,Fa,Fb; 90 scanf("%d%d",&a,&b); 91 root[i]=root[i-1]; 92 Fa=find(a,root[i]); 93 Fb=find(b,root[i]); 94 if (Fa==Fb) printf("1\n"); 95 else printf("0\n"); 96 } 97 } 98 }
4.数论分块
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 int n,k; 5 signed main() 6 { 7 scanf("%lld%lld",&n,&k); 8 int ans=n*k; 9 for (int i=1;i<=n;) 10 { 11 int t,j; 12 t=k/i; 13 j=(t!=0)?min(k/t,n):n; 14 ans-=t*(i+j)*(j-i+1)/2; 15 i=j+1; 16 } 17 printf("%lld\n",ans); 18 }
5.树形背包
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=310; 4 int n,m,s[N],dp[N][N],sz[N]; 5 vector <int> e[N]; 6 void dfs(int x) 7 { 8 dp[x][0]=0; 9 for (int i=0;i<(int)e[x].size();i++) 10 { 11 int u=e[x][i]; 12 dfs(u); 13 for (int j=m+1;j>0;j--) 14 { 15 for (int k=0;k<j;k++) 16 dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[u][k]); 17 } 18 } 19 } 20 int main() 21 { 22 scanf("%d%d",&n,&m); 23 for (int i=1;i<=n;i++) 24 { 25 int k; 26 scanf("%d%d",&k,&s[i]); 27 dp[i][1]=s[i]; 28 e[k].push_back(i); 29 } 30 dfs(0); 31 printf("%d\n",dp[0][m+1]); 32 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=310; 4 int n,m,s[N],dp[N][N],d[N],dfn[N],cnt; 5 int nxt[N]; 6 vector <int> e[N]; 7 void dfs(int x) 8 { 9 dfn[x]=cnt++; 10 for (int i=0;i<(int)e[x].size();i++) 11 { 12 int u=e[x][i]; 13 dfs(u); 14 } 15 nxt[dfn[x]]=cnt; 16 } 17 int main() 18 { 19 scanf("%d%d",&n,&m); 20 for (int i=1;i<=n;i++) 21 { 22 int k; 23 scanf("%d%d",&k,&s[i]); 24 e[k].push_back(i); 25 } 26 dfs(0); 27 memset(dp,-0x3f,sizeof(dp)); 28 memset(dp[0],0,sizeof(dp[0])); 29 for (int i=1;i<=n;i++) d[dfn[i]]=s[i]; 30 for (int i=0;i<=n;i++) 31 { 32 for (int j=0;j<=min(i,m+1);j++) 33 { 34 dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+d[i]); 35 dp[nxt[i]][j]=max(dp[nxt[i]][j],dp[i][j]); 36 } 37 } 38 printf("%d\n",dp[n+1][m+1]); 39 }
6.线段树合并
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define m_k make_pair 3 using namespace std; 4 const int N=100100; 5 int n,m,tot,cnt,first[N],nxt[N*2],point[N*2]; 6 int fa[N][21],de[N],root[N],MAX,ans[N]; 7 vector <pair<int,int> > q[N]; 8 struct node 9 { 10 int ls,rs,MAX,id; 11 }sh[N*50]; 12 void add_edge(int x,int y) 13 { 14 tot++; 15 nxt[tot]=first[x]; 16 first[x]=tot; 17 point[tot]=y; 18 } 19 void dfs(int x,int father) 20 { 21 fa[x][0]=father; 22 for (int i=first[x];i!=-1;i=nxt[i]) 23 { 24 int u=point[i]; 25 if (u==father) continue; 26 de[u]=de[x]+1; 27 dfs(u,x); 28 } 29 } 30 int lca(int a,int b) 31 { 32 if (de[a]>de[b]) swap(a,b); 33 for (int i=20;i>=0;i--) 34 { 35 if (de[fa[b][i]]>=de[a]) 36 b=fa[b][i]; 37 } 38 if (a==b) return a; 39 for (int i=20;i>=0;i--) 40 { 41 if (fa[a][i]!=fa[b][i]) 42 { 43 a=fa[a][i]; 44 b=fa[b][i]; 45 } 46 } 47 return fa[a][0]; 48 } 49 void pushup(int x) 50 { 51 int ls,rs; 52 ls=sh[x].ls;rs=sh[x].rs; 53 sh[x].MAX=max(sh[ls].MAX,sh[rs].MAX); 54 if (sh[ls].MAX==sh[rs].MAX) sh[x].id=min(sh[ls].id,sh[rs].id); 55 if (sh[ls].MAX<sh[rs].MAX) sh[x].id=sh[rs].id; 56 if (sh[ls].MAX>sh[rs].MAX) sh[x].id=sh[ls].id; 57 } 58 void change(int &x,int l,int r,int co,int s) 59 { 60 if (!x) x=++cnt; 61 if (l==r) 62 { 63 sh[x].MAX+=s;sh[x].id=co; 64 return; 65 } 66 int mid=(l+r)>>1; 67 if (co<=mid) change(sh[x].ls,l,mid,co,s); 68 else change(sh[x].rs,mid+1,r,co,s); 69 pushup(x); 70 } 71 int merge(int a,int b,int l,int r) 72 { 73 if (!a) return b; 74 if (!b) return a; 75 if (l==r) 76 { 77 sh[a].MAX+=sh[b].MAX; 78 return a; 79 } 80 int mid=(l+r)>>1; 81 sh[a].ls=merge(sh[a].ls,sh[b].ls,l,mid); 82 sh[a].rs=merge(sh[a].rs,sh[b].rs,mid+1,r); 83 pushup(a); 84 return a; 85 } 86 void dfs1(int x) 87 { 88 for (int i=first[x];i!=-1;i=nxt[i]) 89 { 90 int u=point[i]; 91 if (u==fa[x][0]) continue; 92 dfs1(u); 93 } 94 root[x]=++cnt; 95 for (int i=0;i<(int)q[x].size();i++) 96 change(root[x],1,MAX,q[x][i].first,q[x][i].second); 97 for (int i=first[x];i!=-1;i=nxt[i]) 98 { 99 int u=point[i]; 100 if (u==fa[x][0]) continue; 101 root[x]=merge(root[x],root[u],1,MAX); 102 } 103 ans[x]=sh[root[x]].MAX?sh[root[x]].id:0; 104 } 105 int main() 106 { 107 tot=-1; 108 memset(nxt,-1,sizeof(nxt)); 109 memset(first,-1,sizeof(first)); 110 scanf("%d%d",&n,&m); 111 for (int i=1;i<n;i++) 112 { 113 int x,y; 114 scanf("%d%d",&x,&y); 115 add_edge(x,y); 116 add_edge(y,x); 117 } 118 dfs(1,1); 119 for (int j=1;j<=20;j++) 120 { 121 for (int i=1;i<=n;i++) 122 fa[i][j]=fa[fa[i][j-1]][j-1]; 123 } 124 for (int i=1;i<=m;i++) 125 { 126 int a,b,c,l; 127 scanf("%d%d%d",&a,&b,&c); 128 l=lca(a,b); 129 q[a].push_back(m_k(c,1)); 130 q[b].push_back(m_k(c,1)); 131 q[l].push_back(m_k(c,-1)); 132 if (l!=1) q[fa[l][0]].push_back(m_k(c,-1)); 133 MAX=max(MAX,c); 134 } 135 dfs1(1); 136 for (int i=1;i<=n;i++) printf("%d\n",ans[i]); 137 }
7.fhq_treap
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN=100100; 4 int n,root,t; 5 struct node 6 { 7 int val,key,si,son[2],g; 8 }sh[MAXN]; 9 deque <int> q; 10 int newnode(int v) 11 { 12 t++; 13 sh[t].si=sh[t].g=1; 14 sh[t].val=v; 15 sh[t].key=rand(); 16 return t; 17 } 18 void pushup(int x) 19 { 20 sh[x].si=sh[x].g+sh[sh[x].son[0]].si+sh[sh[x].son[1]].si; 21 } 22 void split(int now,int k,int &x,int &y) 23 { 24 if (now==0) 25 { 26 x=y=0; 27 return; 28 } 29 if (sh[now].val<=k) 30 { 31 x=now; 32 split(sh[now].son[1],k,sh[now].son[1],y); 33 } 34 else 35 { 36 y=now; 37 split(sh[now].son[0],k,x,sh[now].son[0]); 38 } 39 pushup(now); 40 } 41 int merge(int x,int y) 42 { 43 if (x==0) 44 return y; 45 if (y==0) 46 return x; 47 if (sh[x].key<sh[y].key) 48 { 49 sh[x].son[1]=merge(sh[x].son[1],y); 50 pushup(x); 51 return x; 52 } 53 else 54 { 55 sh[y].son[0]=merge(x,sh[y].son[0]); 56 pushup(y); 57 return y; 58 } 59 } 60 int kth(int now,int k) 61 { 62 if (sh[sh[now].son[0]].si<k && k<=sh[sh[now].son[0]].si+sh[now].g) 63 return now; 64 else 65 if (k<sh[sh[now].son[0]].si+sh[now].g) 66 return kth(sh[now].son[0],k); 67 else 68 return kth(sh[now].son[1],k-sh[sh[now].son[0]].si-sh[now].g); 69 } 70 int find(int x) 71 { 72 q.clear(); 73 int cur; 74 cur=root; 75 while (sh[cur].son[x>sh[cur].val]!=0 && sh[cur].val!=x) 76 q.push_back(cur),cur=sh[cur].son[x>sh[cur].val]; 77 q.push_back(cur); 78 return cur; 79 } 80 void updata() 81 { 82 while (!q.empty()) 83 { 84 pushup(q.back()); 85 q.pop_back(); 86 } 87 } 88 int main() 89 { 90 srand(time(0)); 91 root=0; 92 scanf("%d",&n); 93 for (int i=1;i<=n;i++) 94 { 95 int x,op; 96 scanf("%d%d",&op,&x); 97 if (op==1) 98 { 99 int cur=find(x); 100 if (sh[cur].val==x) 101 { 102 sh[cur].g++; 103 updata(); 104 } 105 else 106 { 107 int a,b; 108 split(root,x,a,b); 109 root=merge(merge(a,newnode(x)),b); 110 } 111 } 112 if (op==2) 113 { 114 int cur=find(x); 115 sh[cur].g--; 116 updata(); 117 if (sh[cur].g==0) 118 { 119 int a,b,c; 120 split(root,x,a,b); 121 split(a,x-1,a,c); 122 c=merge(sh[c].son[0],sh[c].son[1]); 123 root=merge(merge(a,b),c); 124 } 125 } 126 if (op==3) 127 { 128 int a,b; 129 split(root,x-1,a,b); 130 printf("%d\n",sh[a].si+1); 131 root=merge(a,b); 132 } 133 if (op==4) 134 { 135 printf("%d\n",sh[kth(root,x)].val); 136 } 137 if (op==5) 138 { 139 int a,b; 140 split(root,x-1,a,b); 141 printf("%d\n",sh[kth(a,sh[a].si)].val); 142 root=merge(a,b); 143 } 144 if (op==6) 145 { 146 int a,b; 147 split(root,x,a,b); 148 printf("%d\n",sh[kth(b,1)].val); 149 root=merge(a,b); 150 } 151 } 152 }
8.BSGS
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 int p,b,n,sp; 5 map <int,int> t; 6 int m_pow(int a,int b) 7 { 8 int ans=1; 9 while (b) 10 { 11 if (b&1) ans=(ans*a)%p; 12 b>>=1; 13 a=(a*a)%p; 14 } 15 return ans; 16 } 17 int inv(int x) 18 { 19 return m_pow(x,p-2); 20 } 21 int bsgs() 22 { 23 sp=sqrt(p); 24 int x=1; 25 for (int i=0;i<sp;i++) 26 { 27 t[x]=i; 28 if (x==n) return i; 29 x=(x*b)%p; 30 } 31 for (int i=2;i<=sp;i++) 32 { 33 int div=m_pow(b,sp*(i-1)); 34 div=inv(div); 35 x=(n*div)%p; 36 if (t[x]) return t[x]+sp*(i-1); 37 } 38 return -1; 39 } 40 signed main() 41 { 42 scanf("%lld%lld%lld",&p,&b,&n); 43 if (n==0) 44 { 45 printf("1\n"); 46 return 0; 47 } 48 int ans=bsgs(); 49 if (ans==-1) printf("no solution\n"); 50 else printf("%lld\n",ans); 51 }
9.exCRT/CRT
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int N=1e5+100; 5 int n,a[N],b[N]; 6 int mul(int a,int b,int mod) 7 { 8 bool bl=0; 9 if (a<0) bl^=1; 10 if (b<0) bl^=1; 11 a=abs(a);b=abs(b); 12 int ans=0; 13 while (b) 14 { 15 if (b&1ll) ans=(ans+a)%mod; 16 b>>=1ll; 17 a=(a+a)%mod; 18 } 19 return (bl)?-ans:ans; 20 } 21 int gcd(int a,int b) 22 { 23 if (b==0) return a; 24 else return gcd(b,a%b); 25 } 26 void exgcd(int a,int b,int &x,int &y) 27 { 28 if (b==0) 29 { 30 x=1;y=0; 31 return; 32 } 33 exgcd(b,a%b,x,y); 34 int z=x; 35 x=y;y=z-(a/b)*y; 36 } 37 int lcm(int a,int b) 38 { 39 int g=gcd(a,b); 40 return (a/g)*b; 41 } 42 int work(int a,int b,int c) 43 { 44 int g=gcd(a,b); 45 a/=g;b/=g;c/=g; 46 int x,y; 47 exgcd(a,b,x,y); 48 x=mul(x,c,b);x=(x%b+b)%b; 49 return x; 50 } 51 signed main() 52 { 53 scanf("%lld",&n); 54 for (int i=1;i<=n;i++) 55 scanf("%lld%lld",&a[i],&b[i]); 56 for (int i=2;i<=n;i++) 57 { 58 int x=work(a[1],a[i],b[i]-b[1]); 59 int na=a[1]; 60 a[1]=lcm(a[1],a[i]); 61 b[1]=(mul(na,x,a[1])+b[1])%a[1]; 62 // b[1]=a[1]*x+b[1]; 63 } 64 printf("%lld\n",b[1]); 65 }
10.Miller Robin素数测试
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 int n; 5 int p[8]={2,3,5,7,11,13,17,47}; 6 int mul(int a,int b,int mod) 7 { 8 int ans=0; 9 while (b) 10 { 11 if (b&1) ans=(ans+a)%mod; 12 b>>=1; 13 a=(a+a)%mod; 14 } 15 return ans; 16 } 17 int m_pow(int a,int b,int mod) 18 { 19 int ans=1; 20 while (b) 21 { 22 if (b&1) ans=mul(ans,a,mod); 23 b>>=1; 24 a=mul(a,a,mod); 25 } 26 return ans; 27 } 28 bool miller_robin(int n,int a) 29 { 30 int d,r; 31 d=n-1;r=0; 32 while (d%2==0) 33 { 34 d>>=1; 35 r++; 36 } 37 int now=m_pow(a,d,n); 38 if (now==1) return true; 39 for (int i=0;i<r;i++) 40 { 41 if (now==n-1) return true; 42 now=mul(now,now,n); 43 } 44 return false; 45 } 46 bool check(int n) 47 { 48 if (n<2) return false; 49 for (int i=0;i<8;i++) 50 { 51 if (n==p[i]) return true; 52 if (n%p[i]==0) return false; 53 if (!miller_robin(n,p[i]) && n>p[i]) return false; 54 } 55 return true; 56 } 57 signed main() 58 { 59 scanf("%lld",&n); 60 if (check(n)) printf("Prime\n"); 61 else printf("Not Prime\n"); 62 }