数据的离散化存储+去重
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+7; 4 int a[maxn]; 5 vector<int> g; 6 int getid(int x) 7 { 8 return lower_bound(g.begin(),g.end(),x)-g.begin()+1; 9 } 10 int main() 11 { 12 int n; 13 cin>>n; 14 for(int i=0;i<n;++i){ 15 cin>>a[i]; 16 g.push_back(a[i]); 17 } 18 sort(g.begin(),g.end()); 19 g.erase(unique(g.begin(),g.end()),g.end()); 20 return 0; 21 }
KMP
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstring> 4 using namespace std; 5 void get_next(char *str,int *next,int len) 6 { 7 int i=0,j=-1; 8 next[0]=-1; 9 while(i<len) 10 { 11 if(j==-1||str[i]==str[j]){ 12 ++i; 13 ++j; 14 next[i]=j; 15 }else 16 j=next[j]; 17 } 18 } 19 int Index_KMP(char *s1,char *s2,int len1,int len2) 20 { 21 int i=0,j=-1; 22 int next[200]; 23 get_next(s2,next,len2); 24 while(i<len1&&j<len2) 25 { 26 if(j==-1||s1[i]==s2[j]){ 27 ++i; 28 ++j; 29 }else 30 j=next[j]; 31 } 32 if(j>=len2) 33 return i-j+1; 34 else 35 return 0; 36 } 37 int main() 38 { 39 char s1[200],s2[200]; 40 cin>>s1>>s2; 41 int len1=strlen(s1); 42 int len2=strlen(s2); 43 int pos=Index_KMP(s1,s2,len1,len2); 44 cout<<pos<<endl; 45 return 0; 46 }
AC自动机(指针版)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+7; 4 typedef struct node{ 5 char c; 6 struct node *next[26]; 7 struct node *fail,*father; 8 bool flag; 9 void init() 10 { 11 for(int i=0;i<26;++i) 12 next[i]=NULL; 13 flag=false; 14 } 15 } node; 16 node *root=new node; 17 void build(char str[][10010],int num) 18 { 19 int len,x; 20 node *p,*r; 21 root->fail=root; 22 for(int i=0;i<num;++i){ 23 p=root; 24 len=strlen(str[i]); 25 for(int j=0;j<len;++j){ 26 x=str[i][j]-'a'; 27 if(!p->next[x]){ 28 p->next[x]=new node; 29 p->next[x]->init(); 30 p->next[x]->fail=root; 31 p->next[x]->father=p; 32 p->next[x]->c=str[i][j]; 33 } 34 p=p->next[x]; 35 if(j==len-1) 36 p->flag=true; 37 } 38 } 39 queue<node*> q; 40 q.push(root); 41 while(!q.empty()) 42 { 43 p=q.front(); 44 q.pop(); 45 for(int i=0;i<26;++i){ 46 if(p->next[i]) 47 q.push(p->next[i]); 48 } 49 if(p==root) 50 continue; 51 x=p->c-'a'; 52 r=p->father->fail; 53 if(r->next[x]&&r->next[x]!=p) 54 p->fail=r->next[x]; 55 } 56 } 57 int AC_automachine(char str[]) 58 { 59 int ans=0,len=strlen(str),x; 60 node *p=root; 61 for(int i=0;i<len;++i){ 62 x=str[i]-'a'; 63 if(p->next[x]){ 64 p=p->next[x]; 65 if(p->flag) 66 ans++; 67 }else{ 68 p=p->fail; 69 if(p->flag) 70 ans++; 71 if(p!=root) 72 --i; 73 } 74 //cout<<i<<endl; 75 } 76 return ans; 77 } 78 char str[51][10010]; 79 char s[maxn]; 80 int main() 81 { 82 cin.tie(0); 83 ios::sync_with_stdio(false); 84 //freopen("in.txt","r",stdin); 85 int n,t; 86 cin>>t; 87 while(t--) 88 { 89 root->init(); 90 cin>>n; 91 for(int i=0;i<n;++i) 92 cin>>str[i]; 93 build(str,n); 94 cin>>s; 95 cout<<AC_automachine(s)<<endl; 96 } 97 return 0; 98 }
AC自动机(数组版)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+7; 4 const int N=5e5+7; 5 struct Aho{ 6 struct Node{ 7 int next[26]; 8 int fail,cnt; 9 }node[N]; 10 int size; 11 void init() 12 { 13 for(int i=0;i<N;++i){ 14 memset(node[i].next,0,sizeof(node[i].next)); 15 node[i].fail=node[i].cnt=0; 16 } 17 size=1; 18 } 19 void insert(char *str) 20 { 21 int len=strlen(str); 22 int now=0; 23 for(int i=0;i<len;++i){ 24 int x=str[i]-'a'; 25 if(!node[now].next[x]) 26 node[now].next[x]=size++; 27 now=node[now].next[x]; 28 } 29 node[now].cnt++; 30 } 31 void build()//构建fail指针 32 { 33 queue<int> q; 34 node[0].fail=-1; 35 q.push(0); 36 while(!q.empty()) 37 { 38 int u=q.front(); 39 q.pop(); 40 for(int i=0;i<26;++i){ 41 if(node[u].next[i]){ 42 if(u==0)//如果是根节点的子节点,那么fail指针一定指向根 43 node[node[u].next[i]].fail=0; 44 else{ 45 int v=node[u].fail; 46 while(v!=-1) 47 { 48 if(node[v].next[i]){//如果父节点的fail指针指向的节点指向点有对应的子节点, 49 //就将fail指针指向此节点 50 node[node[u].next[i]].fail=node[v].next[i]; 51 break; 52 } 53 v=node[v].fail; 54 } 55 if(v==-1) 56 node[node[u].next[i]].fail=0; 57 } 58 q.push(node[u].next[i]); 59 } 60 } 61 } 62 } 63 int get(int u) 64 { 65 int ans=0; 66 while(u) 67 { 68 ans+=node[u].cnt; 69 node[u].cnt=0; 70 u=node[u].fail; 71 } 72 return ans; 73 } 74 int math(char *s) 75 { 76 int len=strlen(s); 77 int ans=0,now=0; 78 for(int i=0;i<len;++i){ 79 int x=s[i]-'a'; 80 if(node[now].next[x]) 81 now=node[now].next[x]; 82 else{ 83 int p=node[now].fail; 84 while(p!=-1&&node[p].next[x]==0) 85 p=node[p].fail; 86 if(p==-1) 87 now=0; 88 else 89 now=node[p].next[x]; 90 } 91 if(node[now].cnt) 92 ans+=get(now); 93 } 94 return ans; 95 } 96 }aho; 97 char s[maxn]; 98 int main() 99 { 100 ios::sync_with_stdio(false); 101 int t,n; 102 cin>>t; 103 while(t--) 104 { 105 aho.init(); 106 cin>>n; 107 for(int i=0;i<n;++i){ 108 cin>>s; 109 aho.insert(s); 110 } 111 aho.build(); 112 cin>>s; 113 int ans=aho.math(s); 114 cout<<ans<<endl; 115 } 116 return 0; 117 }
并查集
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1010; 4 5 void Init(int *father,int *rank) 6 { 7 for(int i=0;i<maxn;++i){ 8 father[i]=i; 9 rank[i]=0; 10 } 11 } 12 //int FindSet1(int x,int *father) 13 //{ 14 // int r=x,j; 15 // while(x!=father[x]) 16 // x=father[x]; 17 // while(r!=x) 18 // { 19 // j=father[r]; 20 // father[r]=x; 21 // r=j; 22 // } 23 // return x; 24 //} 25 int FindSet2(int x,int *father) 26 { 27 28 if(x!=father[x]) 29 father[x]=FindSet2(father[x],father); 30 return father[x]; 31 } 32 bool Union(int x,int y,int *father,int *rank) 33 { 34 x=FindSet1(x,father); 35 y=FindSet1(y,father); 36 if(x==y) 37 return false; 38 if(rank[x]>rank[y]) 39 father[y]=x; 40 else{ 41 if(rank[x]==rank[y]) 42 rank[y]++; 43 father[x]=y; 44 } 45 return true; 46 } 47 int main() 48 { 49 int n,x,y; 50 int father[maxn],rank[maxn]; 51 Init(father,rank); 52 cin>>n; 53 for(int i=0;i<n;++i){ 54 cin>>x>>y; 55 bool flag=Union(x,y,father,rank); 56 if(flag) 57 cout<<"Successful"<<endl; 58 else 59 cout<<"Set has exist"<<endl; 60 } 61 return 0; 62 }
二分查找
1 #include<stdio.h> 2 3 int search(int tar,int a[],int len) 4 { 5 int ret=-1; 6 int left=0,right=len-1,mid; 7 while(right>left) 8 { 9 mid=(right+left)/2; 10 if(a[mid]==tar){ 11 ret=mid; 12 break; 13 }else if(a[mid]>tar){ 14 right=mid-1; 15 }else{ 16 left=mid+1; 17 } 18 } 19 return ret; 20 } 21 int main() 22 { 23 int n,i; 24 int a[]={1,2,7,8,18,45,66,67,88,169,198}; 25 scanf("%d",&n); 26 i=search(n,a,sizeof(a)/sizeof(a[0])); 27 printf("%d\n",i); 28 return 0; 29 }
矩阵快速幂
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int NUM=5; 5 const int mod=998244353; 6 struct Mat{ 7 int n,m; 8 ll a[NUM][NUM]; 9 }; 10 Mat mul(Mat a,Mat b) 11 { 12 Mat ans; 13 ans.n=a.n; 14 ans.m=b.m; 15 for(int i=0;i<ans.n;++i) 16 for(int j=0;j<ans.m;++j){ 17 ans.a[i][j]=0; 18 for(int k=0;k<a.m;++k){ 19 ans.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod; 20 ans.a[i][j]%=mod; 21 } 22 } 23 return ans; 24 } 25 Mat power(Mat a,int num) 26 { 27 Mat ans; 28 ans.n=2; 29 ans.m=1; 30 ans.a[0][0]=ans.a[1][0]=1; 31 while(num) 32 { 33 if(num&1) 34 ans=mul(ans,a); 35 num>>=1; 36 a=mul(a,a); 37 } 38 return ans; 39 } 40 int main() 41 { 42 //freopen("data.txt","r",stdin); 43 //freopen("out1.txt","w",stdout); 44 ios::sync_with_stdio(false); 45 int n; 46 Mat a; 47 a.n=a.m=2; 48 a.a[0][0]=0; 49 a.a[0][1]=a.a[1][0]=a.a[1][1]=1; 50 while(cin>>n) 51 { 52 Mat ans=power(a,n*2+3); 53 cout<<((ans.a[0][1]-1)%mod+mod)%mod<<endl; 54 } 55 return 0; 56 }
欧几里得
1 int gcd(int a,int b) 2 { 3 return b==0?a:gcd(b,a%b); 4 }
拓展欧几里得
1 int exGcd(a a,a b,a &x,a &y) 2 { 3 if(b==0){ 4 x=1;y=0; 5 return a; 6 } 7 int r=exGcd(b,a%b,x,y); 8 int t=x; 9 x=y; 10 y=t-a/b*y; 11 }
线性筛
1 const int maxn=1e6+10; 2 bool isprime[maxn]; 3 int prime[maxn]; 4 int primenum; 5 void getprime(int limit) 6 { 7 primenum=0; 8 memset(isprime,true,sizeof(isprime)); 9 isprime[0]=isprime[1]=false; 10 for(int i=2;i<=limit;++i){ 11 if(isprime[i]) 12 prime[++primenum]=i; 13 for(int j=1;j<=primenum&&i*prime[j]<=limit;++j){ 14 isprime[i*prime[j]]=false; 15 if(i%prime[j]==0) 16 break; 17 } 18 } 19 }
较小组合数求模
1 int num[maxn][maxn]; 2 int C(int n,int k) 3 { 4 if(k>n) 5 return 0; 6 return num[n][k]; 7 } 8 void Cal(int n) 9 { 10 for(int i=0;i<=n;++i){ 11 num[i][0]=1; 12 for(int j=1;j<i;++j) 13 num[i][j]=(C(i-1,j-1)%mod+C(i-1,j)%mod)%mod; 14 num[i][i]=1; 15 } 16 }
矩阵乘法
1 void mult(int **a,int **b,int **c) 2 { 3 memset(c,0,sizeof(c)); 4 for(int i=0;i<N;++i) 5 for(int j=0;j<N;++j) 6 for(int l=0;l<N;++l) 7 c[i][j]+=a[i][l]*b[l][j]; 8 }
求逆元
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 void ex_gcd(LL a,LL b,LL &x,LL &y,LL &d) 5 { 6 if(!b) 7 d=a,x=1,y=0; 8 else { 9 ex_gcd(b,a%b,y,x,d); 10 y-=x*(a/b); 11 } 12 } 13 LL inv1(LL a,LL p) 14 { 15 LL d,x,y; 16 ex_gcd(a,p,x,y,d); 17 return d==1?(x%p+p)%p:-1; 18 } 19 LL inv2(LL a,LL p) 20 { 21 return a==1?1:(p-p/a)*inv(p%t,p)%p; 22 } 23 int main() 24 { 25 LL a,p; 26 while(cin>>a>>p) 27 cout<<inv1(a,p)<<endl; 28 return 0; 29 }
欧拉函数
1 //欧拉函数是求小于等于n的数中与n互质的数的数目 2 #include<bits/stdc++.h> 3 using namespace std; 4 const int maxn=1e6+7; 5 int phi[maxn],prime[maxn]; 6 int tot; 7 void Euler() 8 { 9 phi[1]=1; 10 for(int i=2;i<N;++i){ 11 if(!phi[i]){ 12 phi[i]=i-1; 13 prime[tot++]=i; 14 } 15 for(int j=0;j<tot&&i*prime[j]<maxn;++j){ 16 if(i%prime[j]) 17 phi[i*prime[j]]=phi[i]*(prime[j]-1); 18 else{ 19 phi[i*prime[j]]=phi[i]*prime[j]; 20 break; 21 } 22 } 23 } 24 } 25 int main() 26 { 27 Euler(); 28 return 0; 29 }
中国剩余定理
1 #include<bits/stdc++.h> 2 using namespace std; 3 //n个方程:x=a[i](mod m[i]) (0<=i<n) 4 LL china(int n, LL *a, LL *m){ 5 LL M = 1, ret = 0; 6 for(int i = 0; i < n; i ++) M *= m[i]; 7 for(int i = 0; i < n; i ++){ 8 LL w = M / m[i]; 9 ret = (ret + w * inv(w, m[i]) * a[i]) % M; 10 } 11 return (ret + M) % M; 12 }
Lucas定理
1 LL Lucas(LL n, LL m, int p) 2 { 3 return m ? Lucas(n/p, m/p, p) * comb(n%p, m%p, p) % p : 1; 4 }
高精度求模
1 int get_mod(string a,int mod) 2 { 3 int ans=0; 4 for(int i=0;i<a.size();++i) 5 ans=(ans*10+(a[i]-'0'))%mod; 6 return ans; 7 }
莫队算法
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e6+7; 5 struct node{ 6 int l,r,id; 7 }query[maxn]; 8 ll Ans=0,a[i],ans[maxn]; 9 int pos[maxn],L=0,R=1; 10 bool cmp(node a,node b) 11 { 12 if(pos[a.l]==pos[b.l]) 13 return a.r<b.r; 14 return pos[a.l]<pos[b.l]; 15 } 16 void add(int x) 17 { 18 19 } 20 21 void del(int x) 22 { 23 24 } 25 int main() 26 { 27 int n,m,sz; 28 cin>>n>>m; 29 sz=sqrt(n); 30 for(int i=1;i<=n;++i){ 31 cin>>a[i]; 32 a[i]+=a[i-1]; 33 pos[i]=i/sz; 34 } 35 for(int i=1;i<=m;++i){ 36 cin>>query[i].l>>query[i].r; 37 query[i].id=i; 38 } 39 sort(query+1,query+1+m); 40 for(int i=1;i<=m;++i){ 41 while(L<query[i].l) 42 { 43 del(L-1); 44 ++L; 45 } 46 while(L>query[i].l) 47 { 48 --L; 49 add(L-1); 50 } 51 while(R<query[i].r) 52 { 53 ++R; 54 add(R); 55 } 56 while(R>query[i].r) 57 { 58 del(R); 59 --R; 60 } 61 ans[query[i].id]=Ans; 62 } 63 for(int i=1;i<=m;++i) 64 cout<<ans[i]<<endl; 65 return 0; 66 }
线段树(点修改)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=100010; 4 int a[maxn],tree[maxn*2]; 5 void build(int l,int r,int k) 6 { 7 if(l>r) 8 return ; 9 if(l==r) 10 tree[k]=a[l]; 11 int mid=(l+r)>>1; 12 build(l,mid,2*k); 13 build(mid+1,r,2*k+1); 14 tree[k]=tree[2*k]+tree[2*k+1]; 15 } 16 void change(int l,int r,int cl,int cr,int k,int x) 17 { 18 if(l>cr||r<cl||l>r) 19 return ; 20 if(l==r){ 21 tree[k]+=x; 22 return; 23 } 24 int mid=(l+r)>>1; 25 change(l,mid,cl,cr,2*k,x); 26 change(mid+1,r,cl,cr,2*k+1,x); 27 tree[k]=tree[k]=tree[2*k]+tree[2*k+1]; 28 } 29 int query(int l,int r,int ql,int qr,int k) 30 { 31 if(l>cr||r<cl||l>r) 32 return 0; 33 if(l>ql&&r<qr) 34 return tree[k]; 35 int mid=(l+r)>>1; 36 return query(l,mid,ql,qr,2*k)+query(mid+1,r,ql,qr,2*k+1); 37 } 38 int main() 39 { 40 int n; 41 cin>>n; 42 for(int i=1;i<=n;++i) 43 cin>>a[i]; 44 build(1,n,1); 45 46 return 0; 47 }
线段树(区间修改)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 int a[maxn]; 5 int sum[maxn<<2],exc[maxn<<2]; 6 void maintain(int k) 7 { 8 sum[k]=sum[k<<1]+sum[k<<1|1]; 9 } 10 void pushdown(int lenl,int lenr,int k)//标记下放,并更细节点信息 11 { 12 if(exc[k]){ 13 exc[k<<1]=exc[k]; 14 exc[k<<1|1]=exc[k]; 15 sum[k<<1]=exc[k]*lenl; 16 sum[k<<1|1]=exc[k]*lenr; 17 exc[k]=0; 18 } 19 } 20 void build(int l,int r,int k) 21 { 22 if(l>r) 23 return ; 24 if(l==r){ 25 sum[k]=a[l]; 26 exc[k]=0; 27 return ; 28 } 29 int mid=(l+r)>>1; 30 build(l,mid,k<<1); 31 build(mid+1,r,k<<1|1); 32 maintain(k); 33 } 34 void change(int l,int r,int cl,int cr,int k,int newp) 35 { 36 if(l>r||cl>r||cr<l) 37 return ; 38 if(l>=cl&&r<=cr){ 39 sum[k]=newp*(r-l+1);//在发现现在区域小于需要更新区域时 40 exc[k]=newp;//更新节点的结果,并增加延迟标记exc,用于之后的标记下放 41 return ; 42 } 43 int mid=(l+r)>>1; 44 pushdown(mid-l+1,r-mid,k); 45 change(l,mid,cl,cr,k<<1,newp); 46 change(mid+1,r,cl,cr,k<<1|1,newp); 47 maintain(k); 48 } 49 int query(int l,int r,int ql,int qr,int k) 50 { 51 if(l>r||ql>r||qr<l) 52 return 0; 53 if(l>=ql&&r<=qr) 54 return sum[k]; 55 int mid=(l+r)>>1,ans=0; 56 pushdown(mid-l+1,r-mid,k);//每一层询问执行到这一步,为了下一次递归更新叶节点信息 57 if(mid>=l) 58 ans+=query(l,mid,ql,qr,k<<1); 59 if(mid<r) 60 ans+=query(mid+1,r,ql,qr,k<<1|1); 61 return ans; 62 } 63 int main() 64 { 65 ios::sync_with_stdio(false); 66 //freopen("in.txt","r",stdin); 67 int n,m,cmd,l,r,newp; 68 cin>>n; 69 for(int i=1;i<=n;++i) 70 cin>>a[i]; 71 build(1,n,1); 72 cin>>m; 73 for(int i=0;i<m;++i){ 74 cin>>cmd>>l>>r; 75 if(cmd){ 76 cin>>newp; 77 change(1,n,l,r,1,newp); 78 }else 79 cout<<query(1,n,l,r,1)<<endl; 80 } 81 return 0; 82 }
树上倍增
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+7; 4 vector<int> mp[maxn]; 5 int dep[maxn],fa[maxn][40],size[maxn]; 6 void dfs(int x,int last) 7 { 8 int v; 9 dep[x]=dep[last]+1; 10 fa[x][0]=last; 11 size[x]=1; 12 for(int i=0;i<mp[x].size();++i){ 13 v=mp[x][i]; 14 if(v!=last){ 15 dfs(v,x); 16 size[x]+=size[i]; 17 } 18 } 19 } 20 int lca(int a,int b,int n) 21 { 22 for(int j=1;j<=20;++j) 23 for(int i=1;i<=n;++i) 24 fa[i][j]=fa[fa[i][j-1]][j-1]; 25 if(dep[a]<dep[b]) 26 swap(a,b); 27 int d=dep[a]-dep[b]; 28 for(int i=0;i<=20;++i) 29 if((1<<i)&d) 30 a=fa[a][d]; 31 for(int i=20;i>=0;--i) 32 if(fa[a][i]!=fa[b][i]){ 33 a=fa[a][i]; 34 b=fa[b][i]; 35 } 36 if(a==b) 37 return a; 38 else 39 return fa[a][0]; 40 } 41 int main() 42 { 43 int n,u,v; 44 cin>>n; 45 for(int i=0;i<n;++i){ 46 cin>>u>>V; 47 mp[u].push_back(v); 48 mp[v].push_back(u); 49 } 50 dfs(1,0); 51 cin>>u>>v; 52 cout<<lca(u,v,n)<<endl; 53 return 0; 54 }
树链剖分
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=3e4+7; 4 const int INF=1<<30; 5 int weight[maxn],id[maxn],son[maxn],dep[maxn]; 6 int father[maxn],size[maxn],root[maxn]; 7 int idx=0; 8 struct node{ 9 int l,r; 10 int maxx,sum; 11 }tree[maxn<<2]; 12 vector<int> g[maxn]; 13 void dfs(int x,int last,int d) 14 { 15 dep[x]=d; 16 size[x]=1; 17 father[x]=last; 18 son[x]=0; 19 int v; 20 for(int i=0;i<g[x].size();++i){ 21 v=g[x][i]; 22 if(v==last) 23 continue; 24 dfs(v,x,d+1); 25 if(i==0) 26 son[x]=v; 27 else if(size[son[x]]<size[v]) 28 son[x]=v; 29 size[x]+=size[v]; 30 } 31 } 32 void connect(int x,int r) 33 { 34 int v; 35 root[x]=r; 36 id[x]=++idx; 37 if(son[x]!=0){ 38 connect(son[x],r); 39 for(int i=0;i<g[x].size();++i){ 40 v=g[x][i]; 41 if(v!=father[x]&&v!=son[x]) 42 connect(v,v); 43 } 44 } 45 } 46 void build(int l,int r,int k) 47 { 48 if(l>r) 49 return ; 50 tree[k].l=l; 51 tree[k].r=r; 52 if(l==r) 53 return ; 54 int mid=(l+r)>>1; 55 build(l,mid,k<<1); 56 build(mid+1,r,k<<1|1); 57 } 58 void change(int tar,int w,int k) 59 { 60 int l=tree[k].l; 61 int r=tree[k].r; 62 if(l==r){ 63 tree[k].maxx=w; 64 tree[k].sum=w; 65 return ; 66 } 67 int mid=(l+r)>>1; 68 if(tar<=mid) 69 change(tar,w,k<<1); 70 else 71 change(tar,w,k<<1|1); 72 tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx); 73 tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; 74 } 75 int query_max(int ql,int qr,int k) 76 { 77 int l=tree[k].l; 78 int r=tree[k].r; 79 if(ql>r||qr<l) 80 return -INF; 81 if(ql<=l&&qr>=r) 82 return tree[k].maxx; 83 int mid=(l+r)>>1; 84 return max(query_max(ql,qr,k<<1),query_max(ql,qr,k<<1|1)); 85 } 86 int query_sum(int ql,int qr,int k) 87 { 88 int l=tree[k].l; 89 int r=tree[k].r; 90 if(ql>r||qr<l) 91 return 0; 92 if(ql<=l&&qr>=r) 93 return tree[k].sum; 94 int mid=(l+r)>>1; 95 return query_sum(ql,qr,k<<1)+query_sum(ql,qr,k<<1|1); 96 } 97 int Cal_Sum(int qa,int qb) 98 { 99 int sum=0; 100 while(root[qa]!=root[qb]) 101 { 102 if(dep[root[qa]]<dep[root[qb]]) 103 swap(qa,qb); 104 sum+=query_sum(id[root[qa]],id[qa],1); 105 qa=father[root[qa]]; 106 107 } 108 if(id[qa]>id[qb]) 109 swap(qa,qb); 110 sum+=query_sum(id[qa],id[qb],1); 111 return sum; 112 } 113 int Cal_Max(int qa,int qb) 114 { 115 int maxx=-INF; 116 while(root[qa]!=root[qb]) 117 { 118 if(dep[root[qa]]<dep[root[qb]]) 119 swap(qa,qb); 120 maxx=max(maxx,query_max(id[root[qa]],id[qa],1)); 121 qa=father[root[qa]]; 122 } 123 if(id[qa]>id[qb]) 124 swap(qa,qb); 125 maxx=max(maxx,query_max(id[qa],id[qb],1)); 126 return maxx; 127 } 128 int main() 129 { 130 //freopen("in.txt","r",stdin); 131 int n,v,u,q; 132 char cmd[10]; 133 scanf("%d",&n); 134 for(int i=1;i<n;++i){ 135 scanf("%d%d",&u,&v); 136 g[u].push_back(v); 137 g[v].push_back(u); 138 } 139 140 for(int i=1;i<=n;++i) 141 scanf("%d",&weight[i]); 142 dfs(1,1,1); 143 connect(1,1); 144 build(1,n,1); 145 for(int i=1;i<=n;++i) 146 change(id[i],weight[i],1); 147 scanf("%d",&q); 148 for(int i=0;i<q;++i){ 149 scanf("%s%d%d",cmd,&u,&v); 150 if(cmd[0]=='C') 151 change(id[u],v,1); 152 else if(cmd[1]=='S') 153 printf("%d\n",Cal_Sum(u,v)); 154 else 155 printf("%d\n",Cal_Max(u,v)); 156 } 157 return 0; 158 }
SPFA
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+7; const int INF=0x3F; struct node{ int to,len; }; vector<node> g[maxn]; int shortlen[maxn],cnt[maxn]; int n,m,s,t; bool visit[maxn]; bool spfa() { memset(shortlen,INF,sizeof(shortlen)); memset(visit,false,sizeof(visit)); memset(cnt,0,sizeof(cnt)); queue<int> q; q.push(s); shortlen[s]=0; visit[s]=true; while(!q.empty()) { s=q.front(); q.pop(); visit[s]=false; for(int i=0;i<g[s].size();++i){ if(shortlen[s]+g[s][i].len<shortlen[g[s][i].to]){ shortlen[g[s][i].to]=shortlen[s]+g[s][i].len; if(!visit[g[s][i].to]){ visit[g[s][i].to]=true; q.push(g[s][i].to); cnt[g[s][i].to]++; if(cnt[g[s][i]].to>n) return false; } } } } cout<<shortlen[t]<<endl; return true; } int main() { ios::sync_with_stdio(false); //freopen("in.txt","r",stdin); int u,v; node a; cin>>n>>m>>s>>t; for(int i=0;i<m;++i){ cin>>u>>v>>a.len; a.to=v; g[u].push_back(a); a.to=u; g[v].push_back(a); } spfa(); return 0; }
迪杰斯特拉
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 const int INF=65535; 9 const int maxn=110; 10 unsigned int mp[maxn][maxn]; 11 bool visit[maxn]; 12 unsigned int shortlen[maxn]; 13 typedef struct Node{ 14 int dis,v; 15 bool operator < (const Node &cmp) const{//重载小于号,不理解的可以直接用。作用相当于定义一个优先队列的比较规则 16 return dis > cmp.dis; 17 } 18 }Node; 19 void Dijkstra(int start,int num) 20 { 21 int value; 22 memset(visit,false,sizeof(visit)); 23 memset(shortlen,INF,sizeof(shortlen)); 24 priority_queue<Node> q; 25 shortlen[start]=0; 26 q.push({0,start});//起点放入队列 27 while(!q.empty()) 28 { 29 Node a=q.top();//取出 30 q.pop(); 31 start=a.v; 32 value=shortlen[start]; 33 visit[start]=true;//记为访问过 34 for(int i=1;i<=num;++i){ 35 if(i==start) 36 continue; 37 if(mp[start][i]<INF&&visit[i]==false){ 38 if(mp[start][i]+value<shortlen[i]) 39 shortlen[i]=mp[start][i]+value;//更新数组 40 q.push({shortlen[i],i}); 41 } 42 } 43 } 44 } 45 int main() 46 { 47 // freopen("in.txt","r",stdin); 48 int numv; 49 int x,y,w,v; 50 cout<<"InPut the number of v"<<endl; 51 cin>>numv; 52 memset(mp,INF,sizeof(mp)); 53 cout<<"Build Map"<<endl; 54 while(cin>>x>>y&&(x||y)) 55 { 56 cin>>w; 57 mp[x][y]=w; 58 mp[y][x]=w; 59 } 60 cout<<"Input the start"<<endl; 61 cin>>v; 62 63 Dijkstra(v,numv); 64 for(int i=1;i<=numv;++i) 65 cout<<"i="<<i<<" shortlen="<<shortlen[i]<<endl; 66 cout<<endl; 67 return 0; 68 }
克鲁斯卡尔
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=110; 4 typedef struct{ 5 int begin,end,weight; 6 }Edge; 7 int FindSet(int x,int *father) 8 { 9 10 if(x!=father[x]) 11 father[x]=FindSet(father[x],father); 12 return father[x]; 13 } 14 bool Union(int x,int y,int *father,int *rank) 15 { 16 x=FindSet(x,father); 17 y=FindSet(y,father); 18 if(x==y) 19 return false; 20 if(rank[x]>rank[y]) 21 father[y]=x; 22 else{ 23 if(rank[x]==rank[y]) 24 rank[y]++; 25 father[x]=y; 26 } 27 return true; 28 } 29 bool cmp(Edge a,Edge b) 30 { 31 return a.weight<b.weight; 32 } 33 bool isfull(bool *flag,int n) 34 { 35 for(int i=0;i<n;++i){ 36 if(!flag[i]) 37 return false; 38 } 39 return true; 40 } 41 int main() 42 { 43 // freopen("in.txt","r",stdin); 44 Edge a[maxn]; 45 bool flag[maxn]; 46 int v,e; 47 cin>>v>>e; 48 memset(flag,false,sizeof(flag)); 49 for(int i=0;i<e;++i) 50 cin>>a[i].begin>>a[i].end>>a[i].weight; 51 int father[maxn],rank[maxn]; 52 for(int i=0;i<v;++i){ 53 father[i]=i; 54 rank[i]=0; 55 } 56 sort(a,a+e,cmp); 57 for(int i=0;i<v;++i){ 58 if(isfull(flag,v)) 59 break; 60 Union(a[i].begin,a[i].end,father,rank); 61 cout<<"("<<a[i].begin<<","<<a[i].end<<")"<<endl; 62 flag[a[i].begin]=true; 63 flag[a[i].end]=true; 64 } 65 return 0; 66 }
普里姆
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=1<<30; 4 const int maxn=110; 5 typedef struct { 6 int mp[maxn][maxn]; 7 int number; 8 }Graph; 9 void prim(Graph &a) 10 { 11 int min,i,j,k; 12 int adj[maxn],lowcost[maxn]; 13 lowcost[0]=0; 14 adj[0]=0; 15 for(int i=1;i<a.number;++i){ 16 lowcost[i]=a.mp[0][i]; 17 adj[i]=0; 18 } 19 for(int i=1;i<a.number;++i){ 20 int min=INF; 21 int j=1,k=0; 22 while(j < a.number) 23 { 24 if( lowcost[j]!=0 && lowcost[j]<min){ 25 min = lowcost[j]; 26 k=j; 27 } 28 j++; 29 } 30 cout<<"("<<adj[k]<<","<<k<<")"<<endl; 31 lowcost[k]=0; 32 for(int j=1;j<a.number;++j){ 33 if(lowcost[j]!=0 && a.mp[k][j]<lowcost[j]){ 34 lowcost[j]=a.mp[k][j]; 35 adj[j]=k; 36 } 37 } 38 } 39 } 40 int main() 41 { 42 freopen("in.txt","r",stdin); 43 Graph a; 44 int v,e,x,y,w; 45 cin>>v>>e; 46 a.number=v; 47 for(int i=0;i<v;++i) 48 for(int j=0;j<v;++j) 49 a.mp[i][j]=INF; 50 for(int i=0;i<v;++i) 51 a.mp[i][i]=0; 52 for(int i=0;i<e;++i){ 53 cin>>x>>y>>w; 54 a.mp[x][y]=w; 55 a.mp[y][x]=w; 56 } 57 prim(a); 58 return 0; 59 }
tarjan求强连通分量+缩点
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e4+7; 4 vector<int> g[maxn]; 5 vector<int> newp[maxn]; 6 int dfn[maxn],low[maxn],sccno[maxn]; 7 int idx=0; 8 bool visit[maxn]; 9 stack<int> s; 10 void tarjan(int u) 11 { 12 dfn[u]=low[u]=++idx; 13 s.push(u); 14 visit[u]=true; 15 int v; 16 for(int i=0;i<g[u].size();++i){ 17 v=g[u][i]; 18 if(dfn[v]==0){ 19 tarjan(v); 20 low[u]=min(low[u],low[v]); 21 }else if(visit[v]) 22 low[u]=min(low[u],dfn[v]); 23 } 24 if(dfn[u]==low[u]) 25 do{ 26 v=s.top(); 27 s.pop(); 28 sccno[v]=u;//Ëõµã 29 visit[v]=false; 30 }while(u!=v); 31 } 32 void suodian(int n) 33 { 34 int v,u; 35 for(int i=1;i<=n;++i){ 36 for(int j=0;j<g[i].size();++j){ 37 u=g[i][j]; 38 if(sccno[i]==u) 39 continue; 40 if(w[u]==0) 41 continue; 42 if(u!=sccno[u]){ 43 w[sccno[u]]+=w[u]; 44 w[u]=0; 45 }else 46 newp[sccno[i]].push_back(u); 47 } 48 } 49 } 50 int main() 51 { 52 ios::sync_with_stdio(false); 53 //freopen("in.txt","r",stdin); 54 int n,m,u,v; 55 memset(dfn,0,sizeof(dfn)); 56 cin>>n>>m; 57 for(int i=1;i<=n;++i) 58 cin>>w[i]; 59 for(int i=1;i<=m;++i){ 60 cin>>u>>v; 61 g[u].push_back(v); 62 } 63 for(int i=1;i<=n;++i) 64 sccno[i]=i; 65 tarjan(1); 66 suodian(n); 67 return 0; 68 }
拓扑排序
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=110; 4 const int INF=1<<30; 5 int mp[maxn][maxn]£¬in[maxn]; 6 int cnt=0; 7 bool clear(int n) 8 { 9 for(int i=0;i<n;++i) 10 if(in[i]) 11 return false; 12 return true; 13 } 14 void TopSort(int v,int n) 15 { 16 if(clear(n)) 17 return ; 18 cnt++; 19 cout<<v<<" "; 20 for(int i=0;i<n;++i){ 21 if(i==v) 22 continue; 23 mp[i][v]=INF; 24 if(mp[v][i]!=INF){ 25 in[i]--; 26 mp[v][i]=INF; 27 if(in[i]==0) 28 TopSort(i,n); 29 } 30 } 31 } 32 int main() 33 { 34 int n,m,x,y,w; 35 memset(in,0,sizeof(in)); 36 cin>>n>>m; 37 for(int i=0;i<n;++i) 38 for(int j=0;j<n;++j) 39 mp[i][j]=INF; 40 for(int i=0;i<m;++i){ 41 cin>>x>>y>>w; 42 mp[x][y]=w; 43 in[y]++; 44 } 45 for(int i=0;i<n;++i){ 46 if(in[i]==0){ 47 TopSort(i,n); 48 break; 49 } 50 } 51 cout<<endl; 52 if(cnt==n) 53 cout<<"It's AOV"<<endl; 54 else 55 cout<<"It's not AOV"<<endl; 56 return 0; 57 }
来源:https://www.cnblogs.com/SCaryon/p/7373338.html