数据的离散化存储+去重

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
