noip2016考前模板
先是到现在还是靠背的版
线性筛,O(2*N)
1 int flag[N],prim[N],cnt; 2 3 int built(int n) 4 { 5 for(int i=2;i<=n;i++) 6 { 7 if(flag[i]==0) 8 prime[cnt]=i,cnt++; 9 for(int j=0;j<cnt&&i*prim[j]<=n;j++) 10 { 11 flag[i*[prim[j]]=1; 12 if(i%prim[j]==0) 13 break; 14 } 15 } 16 }
exgcd
1 int exgcd(int a,int b,int x,int y) 2 { 3 if(b==0) 4 { 5 x=1; 6 y=0; 7 return a; 8 } 9 int ret=exgcd(b,a%b,y,x); 10 y-=a/b*x; 11 return ret; 12 }
数论相关其他知识点:
•解多组同余方程
考虑两组方程:
x ≡ d1 mod m1
x ≡ d2 mod m2
设设x=k1m1+d1=k2m2+d2,联立可得新方程为
dx=k1m1+d1,mx=lcm(m1,m2)
//表示根本看不出是如何解得的...
则x≡dx mod mx
•逆元:ax≡1 mod p,则min(a)=mb表示a对于p的逆元,p为质数时a=p-2,可以递推得:ans[i]=(p-p/i)*ans[p%i]%p表示i对p的逆元
应用:求a/b mod p=a*b mod mb
•(a^b)%p=a^(b%(p-1)),p为质数
树状数组空间O(n)优于线段树,某些时候线段树会被卡,所以还是必须背
1 int read(int k) 2 { 3 int sum=0; 4 while(k) 5 { 6 sum+=tree[k]; 7 k-=k&-k; 8 } 9 return sum; 10 } 11 12 void add(int k,int num) 13 { 14 while(k<=n) 15 { 16 tree[k]+=num; 17 k+=k&-k; 18 } 19 }
stl heap
1 int main() 2 { 3 make_heap(heap,heap+size); 4 push_heap(heap,heap+(++size)); 5 pop_heap(heap,heap+(size--)); 6 //改变堆的大小:greater<int>()或者自己写compare函数 7 }
已经可以写但是最好复习一下的常用模板
快速幂快速乘
1 int pow(int a,int b) 2 { 3 int ans=1; 4 for(int i=0;b!=0;i++,a*=a) 5 if(b&(1<<i)) 6 ans*=a,b-=(1<<i); 7 return ans; 8 } 9 10 int multi(int a,int b) 11 { 12 int ans=0; 13 for(int i=0;b!=0;i++,a+=a) 14 if(b&(1<<i)) 15 ans+=a,b-=(1<<i); 16 return ans; 17 }
凸包模板
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstdlib> 4 #include<string.h> 5 #include<algorithm> 6 #include<math.h> 7 #define N 1000005 8 using namespace std; 9 int n; 10 double answer; 11 12 struct object 13 { 14 int x,y; 15 }ans[N],point[N]; 16 17 int pow(int a) 18 { 19 return a*a; 20 } 21 22 double dis(object a,object b) 23 { 24 return sqrt(pow(a.x-b.x)+pow(a.y,b.y)); 25 } 26 27 int mul(object a,object b,object c) 28 { 29 return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x); 30 } 31 32 int cmp(object a,object b) 33 { 34 int thi=mul(a,b,point[0]); 35 if(thi==0) 36 return dis(a,point[0])<dis(b,point[0]); 37 return thi>0; 38 } 39 40 void graham() 41 { 42 for(int i=1;i<n;i++) 43 if(point[i].x<point[0].x||point[i].x==point[0].x&&point[i].y<point[0].y) 44 swap(point[0],point[i]); 45 sort(point+1,point+n,cmp); 46 ans[0]=point[0]; 47 ans[1]=point[1]; 48 ans[2]=point[2]; 49 int cnt=2; 50 for(int i=3;i<n;i++) 51 { 52 while(cnt!=0&&mul(point[i],ans[cnt],ans[cnt-1])>=0) 53 cnt--; 54 cnt++; 55 ans[cnt]=point[i]; 56 } 57 } 58 59 int main() 60 { 61 }
kmp
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<cstdlib> 6 #define N 1000000 7 using namespace std; 8 int next[N]; 9 10 void get_next(char &s) 11 { 12 int t1=0,t2=-1,len=strlen(s); 13 next[0]=t2; 14 while(t1<len) 15 { 16 if(t2==0||s[t1]==s[t2]) 17 { 18 t1++; 19 t2++; 20 next[t1]=t2; 21 } 22 else t2=next[t2]; 23 } 24 } 25 26 int kmp(char &s1,char &s2)//s2是短的那个 27 { 28 int ret=0; 29 int len1=strlen(s1),len2=strlen(s2); 30 int t1=0,t2=0; 31 while(t1<len1) 32 { 33 if(s1[t1]==s2[t2]) 34 { 35 t1++; 36 t2++; 37 } 38 else t2=next[t2]; 39 if(t2==len2-1) 40 ret++; 41 } 42 return ret; 43 } 44 45 int main() 46 { 47 }
树上倍增
1 #include<iostream> 2 #include<string.h> 3 #include<stdio.h> 4 #include<algorithm> 5 #include<cstdlib> 6 #define N 100005 7 #define logn 17 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 int n; 11 int begin[N]; 12 int cnt; 13 int deep[N],father[N][logn],ans[N][logn]; 14 15 struct edge 16 { 17 int b,next,weight; 18 }E[N*2]; 19 20 void addedge(int a,int b,int weight) 21 { 22 E[cnt].b=b; 23 E[cnt].next=begin[a]; 24 E[cnt].weight=weight; 25 begin[a]=cnt; 26 cnt++; 27 E[cnt].b=a; 28 E[cnt].next=begin[b]; 29 E[cnt].weight=weight; 30 begin[b]=cnt; 31 cnt++; 32 } 33 34 void DFS(int now) 35 { 36 for(int i=1;i<logn;i++) 37 { 38 if(deep[now]<1<<i) 39 break; 40 father[now][i]=father[father[now][i-1]][i-1]; 41 ans[now][i]=max(ans[now][i-1],ans[father[now][i-1]][i-1]); 42 } 43 for(int i=begin[now];i!=-1;i=E[i].next) 44 if(E[i].b!=father[now][0]) 45 { 46 father[E[i].b][0]=now; 47 ans[E[i].b][0]=E[i].weight; 48 deep[E[i].b]=deep[now]+1; 49 DFS(E[i].b); 50 } 51 } 52 53 int lca(int a,int b) 54 { 55 int ret=-inf; 56 if(deep[a]<deep[b]) 57 swap(a,b); 58 int t=deep[a]-deep[b]; 59 for(int i=0;i<logn;i++) 60 if(t&1<<i) 61 ret=min(ret,ans[a][i]),a=father[a][i]; 62 for(int i=logn-1;i>=0;i--) 63 if(father[a][i]!=father[b][i]) 64 { 65 ret=min(ret,min(ans[a][i],ans[b][i])); 66 a=father[a][i]; 67 b=father[b][i]; 68 } 69 if(a==b) 70 return ret; 71 return min(ret,min(ans[a][0],ans[b][0])); 72 } 73 74 int main() 75 { 76 }
tarjan//未经测试,因为之前写得实在是太丑了临时写的...
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<cstdlib> 5 #include<algorithm> 6 #define N 100005 7 using namespace std; 8 int n; 9 int begin[N]; 10 int cnt; 11 int t; 12 int dfn[N],low[N],flag[N]; 13 int num[N],begin_[N],cnt_,color[N]; 14 15 struct edge 16 { 17 int b,next; 18 }E[N*2],E_[N*2]; 19 20 void addedge(int a,int b) 21 { 22 E[cnt].b=b; 23 E[cnt].next=begin[a]; 24 begin[a]=cnt; 25 cnt++; 26 } 27 28 void addedge_(int a,int b) 29 { 30 E_[cnt].b=b; 31 E_[cnt].next=begin_[a]; 32 begin_[a]=cnt_; 33 cnt_++; 34 } 35 36 class Stack 37 { 38 private: 39 int rear; 40 int stack[N]; 41 public: 42 Stack() 43 { 44 rear=-1; 45 } 46 void Enstack(int x) 47 { 48 rear++; 49 stack[rear]=x; 50 } 51 int Destack() 52 { 53 int x=stack[rear]; 54 rear--; 55 return x; 56 } 57 int Getsize() 58 { 59 return rear+1; 60 } 61 int Getrear() 62 { 63 return stack[rear]; 64 } 65 }ms; 66 67 void DFS(int now) 68 { 69 ms.Enstack(now); 70 low[now]=dfn[now]=t; 71 t++; 72 flag[now]=1; 73 for(int i=begin[now];i!=-1;i=E[i].next) 74 { 75 if(flag[E[i].b]==0) 76 { 77 DFS(E[i].b); 78 low[now]=min(low[now],low[E[i].b]); 79 } 80 else low[now]=min(low[now],dfn[E[i].b]); 81 } 82 flag[now]=0; 83 if(dfn[now]==low[now]) 84 { 85 int thi=-1; 86 while(thi!=now) 87 { 88 thi=ms.Destack(); 89 num[cnt_]++; 90 color[thi]=cnt_; 91 } 92 cnt_++; 93 } 94 } 95 96 void rebuilt(int now) 97 { 98 for(int i=0;i<n;i++) 99 for(int j=begin[i];j!=-1;j=E[j].next) 100 if(color[i]!=color[E[j].b]) 101 addedge_(color[i],color[E[j].b]); 102 } 103 104 //割点dfn[now]<=low[E[i].b] 105 //桥dfn[now]<low[E[i].b] 106 107 int main() 108 { 109 110 }
马拉车//貌似noip是不会考的,字符串部分似乎是只考hash和一点点kmp,hash....虽然没写过还是有信心写对的,主要是没有遇到过需要用hash的题//或者遇到了没考虑过写hash...
1 #include<iostream> 2 #include<string.h> 3 #include<cstdlib> 4 #include<stdio.h> 5 #include<algorithm> 6 #define N 1000005 7 using namespace std; 8 int answer[N*2]; 9 char S[N]; 10 char ms[N*2]; 11 12 void Manacher(char *s) 13 { 14 int len=strlen(s); 15 int l=0; 16 ms[l++]='$',ms[l++]='#'; 17 for(int i=0;i<len;i++) 18 { 19 ms[l++]=s[i]; 20 ms[l++]='#'; 21 } 22 ms[l]=0; 23 int mx=0,id=0; 24 for(int i=0;i<l;i++) 25 { 26 if(mx<=i) 27 answer[i]=1; 28 else answer[i]=min(answer[id*2-i],mx-i); 29 while(ms[i+answer[i]]==ms[i-answer[i]]) 30 answer[i]++; 31 if(i+answer[i]>mx) 32 { 33 mx=i+answer[i]; 34 id=i; 35 } 36 } 37 } 38 39 int main() 40 { 41 }
//其实这就是担心明天考试前突然忘了这些怎么写,U盘又不能用脑读....
//早点睡,UPUP