杂 1.一串数字转字符串
1 2 3 4 5 6 7 8 9 10 string s; int a;cin>>a; stringstream aq; aq<<a; aq>>s; cout<<s; int sum=s.length () ;cout<<sum;
2.求一句英文句子中每个单词有几个字母
string s;
int a, sum=0;
getline(cin, s);//输入一句,不会被空格阻断
stringstream ss;
ss.clear();
ss.str(s);
while(ss >> s)
{
cout<<s.length() <<endl;
}
3.万能模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include<bits/stdc++.h>//万能头 #pragma GCC optimize(2) using namespace std; typedef pair<int,int>PII; //pair typedef unsigned long long ull; typedef long long LL; const int M=2010; const int INF=0x3f3f3f3f;//最大值 const int mod=1e9+7; const int N=2e5+10; int dx[4]={0,1,0,-1}; int dy[4]={-1,0,1,0}; void solve() { } int main() { //只用cin>>,加速 ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); //文件操作 freopen("test.in","r",stdin); int t;cin>>t; while(t--)solve(); return 0; }
4.最小公倍数
1 2 3 4 5 最小公倍数=a*b/最大公因数 二分要先大于目标值 并查集学习网址:https://blog.csdn.net/the_ZED/article/details/105126583?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164318091316780269847701%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164318091316780269847701&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-3-105126583.pc_search_result_cache&utm_term=%E5%B9%B6%E6%9F%A5%E9%9B%86&spm=1018.2226.3001.4187
5.四舍五入
1 2 round()//函数 (int)(a*1.0/b+0.5)
6.去重
1 2 int a[10]; int start=unique(a,a+10)-a;
7.位数
1 2 3 int num; cin>>num; cout<<setw(5)<<setfill('2')<<num<<endl;
8.lc sort()排序定义
1 sort(words.begin(),words.end(),[&](string& a, string &b){}
9.else注意数值是否需要恢复初始化
10.n&(1<<i)是将左移i位的1与n进行按位与,即为保留n的第i位,其余位置零
11.一维数组 邻接表 https://www.bilibili.com/video/BV14o4y1d7vv?spm_id_from=333.337.search-card.all.click
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <bits/stdc++.h> using namespace std; const int maxn = 1e6; int h[maxn], ne[maxn], idx, e[maxn]; void add(int u, int v) { e[idx] = v; ne[idx] = h[u]; h[u] = idx++; } int main() { freopen("a.in", "r", stdin); freopen("b.out", "w", stdout); memset(h, -1, sizeof h); //初始化邻接表 int n, m, u, v, temp = 0; cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> u >> v; add(u, v); if (i == 1) temp = u; } for (int i = 0; i < n; i++) { for (int j = h[i]; j != -1; j = ne[j]) { cout << i << " " << e[j] << endl; // 这是倒着输出,第一次输出的是,一个的最后位置之后往前递推 } } system("pause"); return 0; }
12.小数位输出
1 cout<<fixed<<setprecision(6)<<res<<endl;
13.排列组合
https://zhuanlan.zhihu.com/p/41855459
14.第一个大于
1 2 cout << (lower_bound (a, a + 5 , 1 ) - a) << endl;
1 2 cout << (upper_bound (a, a + 5 , 2 ) - a) << endl;
二分 1 2 3 4 5 6 7 8 9 10 11 12 13 14 while (r1-l1>0.00001 ) { dll mid=(r1+l1)/2 ; if (test(mid)*test(l1)<=0 ) { r1=mid; }else { l1=mid; } } printf ("%.2lf " ,l1);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int main () { int l; int r; while (l <= r) { int mid = (l + r )/ 2 ; if (check()) { ans = mid; l = mid+ 1 ; } else { r = mid-1 ; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include<bits/stdc++.h> using namespace std; int main() { freopen("b.out","w",stdout); int a[10]; for(int i=0;i<10;i++) { a[i]=10; } cout<<"找最靠前的值:"<<endl; int l=0,r=9; while(l<r) { int mid=l+r>>1; if(a[mid]>=10)r=mid; else l=mid+1; } cout<<l<<endl; cout<<"找最靠后的:"<<endl; l=0;r=9; while(l<r) { int mid=l+r+1>>1; if(a[mid]<=10)l=mid; else r=mid-1; } cout<<l<<endl; return 0; }
最大公约数和最小公倍数 1 2 3 int lcm(int a, int b) { return a * b / gcd(a, b); } 最小公倍数 int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } 最大公约数
floyd算法 2021蓝桥javaB路径
https://blog.csdn.net/qq_43196686/article/details/115836954
(耗时极大)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream> using namespace std; typedef long long ll; int min(int a, int b) { return a < b ? a : b; } int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } int lcm(int a, int b) { return a * b / gcd(a, b); } const int N = 2021; int num[N + 1][N + 1]; int main() { for (int i = 1; i < N; i++) { for (int j = i+1; j <= min(i+21,N); j++) { num[i][j] = lcm(i, j); num[j][i] = lcm(i, j); } } for (int k = 1; k <= N; k++) { for (int i = 1; i <= N; i++) { if (num[i][k] == 0) continue; for (int j = 1; j <= N; j++) { if (num[k][j] == 0) continue; else if (num[i][j] == 0 || (num[i][j] > num[i][k] + num[k][j])) num[i][j] = num[i][k] + num[k][j]; } } } cout << num[1][2021] << endl; system("pause"); return 0; }
Dijkstra求最短路 https://www.acwing.com/problem/content/description/851/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #include <bits/stdc++.h> using namespace std; typedef long long ll; int min(int a, int b) { return a < b ? a : b; } int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } int lcm(int a, int b) { return a * b / gcd(a, b); } int edges[550][550]; int dist[550]; //到出发点的距离 int visited[550]; //所有点是否被丢弃 int n, m; int dijkstra(int n1, int m1) { for (int i = 0; i < n1; i++) { int index = -1; dist[1] = 0; for (int j = 1; j <= n1; j++) { if (!visited[j] && (index == -1 || dist[j] < dist[index])) { index = j; } } visited[index] = 1; for (int j = 1; j <= n1; j++) { if (dist[index] + edges[index][j] < dist[j]) { dist[j] = dist[index] + edges[index][j]; } } } if (dist[n1] == 0x3f3f3f3f) { return -1; } else { return dist[n1]; } } int main() { memset(edges, 0x3f, sizeof(edges)); cin >> n >> m; int a, b, c; for (int i = 0; i < m; i++) { cin >> a >> b >> c; edges[a][b] = edges[a][b] > c ? c : edges[a][b]; } memset(dist, 0x3f, sizeof(dist)); memset(visited, 0, sizeof(visited)); cout << dijkstra(n, m) << endl; return 0; }
快速幂 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include<bits/stdc++.h> using namespace std; int test(int a,int b,int c) { int res=1; while(b) { if(b&1)res=(res*a)%c; a=(a*a)%c; b>>=1; } return res; } int main() { cout<<test(2,5,10)<<endl; system("pause"); return 0; }
矩陣快速冪 单个横行和竖行的矩阵值为O,相当于乘法里的1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=1000000009; struct st { ll aa[2][2]; }; st mul(st x,st y) { st c; memset(c.aa,0,sizeof(c.aa)); for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { for(int k=0;k<2;k++) { c.aa[i][j]=(c.aa[i][j]+x.aa[i][k]*y.aa[k][j])%mod;; } } } return c; } ll test(ll a) { st base,base1; memset(base.aa,0,sizeof(base.aa)); memset(base1.aa,0,sizeof(base1.aa)); for(int i=0;i<2;i++) { base.aa[i][i]=1; } base1.aa[0][0]=base1.aa[0][1]=base1.aa[1][0]=1; while(a) { if(a&1)base=mul(base,base1); base1=mul(base1,base1); a>>=1; } return base.aa[0][1]; } int main() { ll num; cin>>num; cout<<test(num)<<endl; return 0; }
https://vjudge.net/contest/479411#problem/F
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include<bits/stdc++.h> 4using namespace std; const int maxn=10e6+1; int a[maxn]; int b[maxn]; void init(int num) { for(int i=1;i<=num;i++) { a[i]=i; } } int find(int key) { if(a[key]==key)return key; else return a[key]=find(a[key]); } void unit(int x1,int y1) { int xx1=find(x1); int yy1=find(y1); if(xx1!=yy1) { a[xx1]=yy1; } } int main() { int n,m; cin>>n>>m; init(n); int a1,b1,c1; for(int i=0;i<m;i++) { cin>>a1>>b1>>c1; if(a1==1) { unit(b1,c1); } else if(a1==2) { if(find(b1)!=find(c1)) { cout<<"NO"<<endl; }else{ cout<<"YES"<<endl; } } } return 0; }
拓扑排序 https://vjudge.net/contest/479411#problem/J
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <bits/stdc++.h> using namespace std; const int maxn = 101; int lin[maxn][maxn]; int ss[maxn]; int value[maxn]; int a, b, m, n; queue<int> qq; void TP() { for (int i = 1; i <= a; i++) { for (int j = 1; j <= a; j++) { if (lin[i][j] == 1) { ss[j]++; } } } for (int i = 1; i <= a; i++) { int k = 1; while (ss[k] != 0) k++; value[i] = k; ss[k] = -1; for (int j = 1; j <= a; j++) { if (lin[k][j] == 1) ss[j]--; } } } int main() { while (scanf("%d%d", &a, &b) != EOF) { if (!(a + b)) break; memset(ss, 0, sizeof(ss)); memset(lin, 0, sizeof(lin)); memset(value, 0, sizeof(value)); for (int i = 0; i < b; i++) { cin >> m >> n; if (i != b) lin[m][n] = 1; } TP(); for (int i = 1; i <= a; i++) { cout << value[i] << " "; } cout << endl; } return 0; }
bfs简单例题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include<iostream> #include<queue> using namespace std; const int maxn= 100001; bool ha[maxn]; int pl[maxn]; queue<int> qq; int bfs(int a1,int b1) { qq.push(a1); ha[a1]=true; int next=0; while(qq.size()) { int temp=qq.front(); qq.pop(); for(int i=0;i<3;i++) { if(i==0)next=temp-1; else if(i==1)next=temp+1; else next=temp*2; if(next<0||next>=maxn)continue; if(!ha[next]) { qq.push(next); ha[next]=true; pl[next]=pl[temp]+1; } if(next==b1)return pl[b1]; } } } int main() { int a,b; cin>>a>>b; if(a>=b) cout<<a-b<<endl; else cout<<bfs(a,b)<<endl; return 0; }
bfs简单例题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <string> #include <math.h> using namespace std;const int maxn=20 ;int n,m;char a[maxn][maxn];int vis[maxn][maxn];int ans=99999 ;int dir[4 ][2 ]={{0 ,-1 },{1 ,0 },{0 ,1 },{-1 ,0 }};int sx,sy,fx,fy;struct node { int x,y; int step; node (int xx,int yy,int ss):x (xx),y (yy),step (ss){ } }; queue<node> q; bool pd (int x,int y) { if (x>=1 &&x<=n&&y>=1 &&y<=m&&vis[x][y]==0 &&a[x][y]!='#' ) { return true ; } else return false ; } void bfs (int x,int y) { vis[x][y]=1 ; q.push (node (x,y,0 )); while (!q.empty ()) { node now=q.front (); q.pop (); for (int i=0 ;i<4 ;i++) { if (now.x+1 >n||now.y+1 >m||now.x-1 <1 ||now.y-1 <1 ) ans=min (ans,now.step); } for (int i=0 ;i<4 ;i++) { int nx=now.x+dir[i][0 ]; int ny=now.y+dir[i][1 ]; if (pd (nx,ny)) { vis[nx][ny]=1 ; q.push (node (nx,ny,now.step+1 )); } } } } int main () { memset (vis,0 ,sizeof (vis)); cin>>n>>m; for (int i=1 ;i<=n;i++) { for (int j=1 ;j<=m;j++) { cin>>a[i][j]; if (a[i][j]=='@' ) { sx=i; sy=j; } } } bfs (sx,sy); if (ans==99999 ) { cout<<-1 ; } else { cout<<ans<<endl; } }
dfs简单例题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <iostream> #include <cstdio> using namespace std; int R, C; int map[105][105]; int mark[105][105] = {0}; int dfs(int i, int j) { int k; if (mark[i][j]) return mark[i][j];// if (i != 0 && map[i - 1][j] < map[i][j]) { k = dfs(i - 1, j) + 1; if (k > mark[i][j]) mark[i][j] = k; } if (i != R - 1 && map[i + 1][j] < map[i][j]) { k = dfs(i + 1, j) + 1; if (k > mark[i][j]) mark[i][j] = k; } if (j != 0 && map[i][j - 1] < map[i][j]) { k = dfs(i, j - 1) + 1; if (k > mark[i][j]) mark[i][j] = k; } if (j != C - 1 && map[i][j + 1] < map[i][j]) { k = dfs(i, j + 1) + 1; if (k > mark[i][j]) mark[i][j] = k; } return mark[i][j]; } int main() { int i, j, k, sum = 0; scanf("%d%d", &R, &C); for (i = 0; i < R; i++) { for (j = 0; j < C; j++) { scanf("%d", &map[i][j]); } } for (i = 0; i < R; i++) { for (j = 0; j < C; j++) { k = dfs(i, j); if (k > sum) sum = k; } } cout << sum + 1 << endl; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include<bits/stdc++.h> using namespace std; const int maxn=10e5; static int trie[maxn][26]; static int count1[maxn]; static int index=0; void insert(string s)//这里是插入数据 { int p=0; for(int i=0;i<s.length();i++) { int u=s[i]-'a'; if(trie[p][u]==0)trie[p][u]=++index; p=trie[p][u]; } count1[p]++; } bool search(string s)//这里是完全搜索数据 { int p=0; for(int i=0;i<s.length();i++) { int u=s[i]-'a'; if(trie[p][u]==0)return false; p=trie[p][u]; } return count1[p]!=0; } bool searchstart(string s)//这里是只搜索前缀是否有共同的 { int p=0; for(int i=0;i<s.length();i++) { int u=s[i]-'a'; if(trie[p][u]==0)return false; p=trie[p][u]; } return true; } int main() { insert("aaa"); cout<<search("aa")<<" "<<search("aaa")<<" "<<search("aaaa")<<endl; cout<<searchstart("a")<<" "<<searchstart("aaa")<<" "<<searchstart("aaaa")<<endl; system("pause"); return 0; }
dfs—1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 问题 C: 【递归入门】组合+判断素数 时间限制: 1 Sec 内存限制: 128 MB 提交: 205 解决: 77 [提交][状态][讨论版][命题人:外部导入] 题目描述 已知 n 个整数b1,b2,…,bn 以及一个整数 k(k<n)。 从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。 例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为: 3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34。 现在,要求你计算出和为素数共有多少种。 例如上例,只有一种的和为素数:3+7+19=29。 输入 第一行两个整数:n , k (1<=n<=20,k<n) 第二行n个整数:x1,x2,…,xn (1<=xi<=5000000) 输出 一个整数(满足条件的方案数)。 样例输入 4 3 3 7 12 19 样例输出 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include<bits/stdc++.h> using namespace std; const int maxn=25; int a[maxn]; int p[maxn]; bool vis[maxn]; int n,k,ans=0,sum; bool test(int num) { if(num<=1) { return false; } for(int i=2;i*i<=num;i++) { if(num%i==0) return false; } return true; } void dfs(int index) { if(index==k+1) { if(test(sum)) ans++; for(int i=1;i<=index-1;i++) { cout<<p[i]<<" "; } cout<<sum; cout<<endl; return ; } for(int i=1;i<=n;i++) { if(vis[i]==false&&i>p[index-1]) { p[index]=i; vis[i]=true; sum+=a[i]; dfs(index+1); vis[i]=false; sum-=a[i]; } } } int main() { cin>>n>>k; for(int i=1;i<=n;i++) { cin>>a[i]; p[i]=i; } dfs(1); cout<<ans<<endl; system("pause"); return 0; }
spfa1–环里有负值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include<bits/stdc++.h> using namespace std; const int maxn=1e5 + 10; int e[maxn],h[maxn],w[maxn],ne[maxn],idx; int dist[maxn],st[maxn]; int m,n; void add(int a,int b,int c) { e[idx]=b; w[idx]=c; ne[idx]=h[a]; h[a]=idx++; } int spfa() { memset(dist,0x3f,sizeof(dist)); dist[1]=0; queue<int>qq; qq.push(1); st[1]=1; while(qq.size()) { auto t=qq.front(); qq.pop(); st[t]=0; for(int i=h[t];i!=-1;i=ne[i]) { int j=e[i]; if(dist[j]>dist[t]+w[i]) { dist[j]=dist[t]+w[i]; if(!st[j]) { qq.push(j); st[j]=1; } } } } if(dist[n]==0x3f3f3f3f) { return -0x3f3f3f3f; } return dist[n]; } int main() { memset(h,-1,sizeof(h)); cin>>n>>m; for(int i=0;i<m;i++) { int a,b,c; cin>>a>>b>>c; add(a,b,c); } if(spfa()==-0x3f3f3f3f){ cout<<"impossible"<<endl; }else{ cout<<dist[n]<<endl; } return 0; }
spfa–判断负环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 #include<bits/stdc++.h> using namespace std; const int maxn=1e5 + 10; int e[maxn],h[maxn],w[maxn],ne[maxn],idx; int dist[maxn],st[maxn],cnt[maxn]; int m,n; void add(int a,int b,int c) { e[idx]=b; w[idx]=c; ne[idx]=h[a]; h[a]=idx++; } bool spfa() { queue<int>qq; for(int i=1;i<=n;i++) { qq.push(i); st[1]=1; } while(qq.size()) { auto t=qq.front(); qq.pop(); st[t]=0; for(int i=h[t];i!=-1;i=ne[i]) { int j=e[i]; if(dist[j]>dist[t]+w[i]) { dist[j]=dist[t]+w[i]; cnt[j]=cnt[t]+1; if(cnt[j]>=n)return true; if(!st[j]) { qq.push(j); st[j]=1; } } } } return false; } int main() { memset(h,-1,sizeof(h)); cin>>n>>m; for(int i=0;i<m;i++) { int a,b,c; cin>>a>>b>>c; add(a,b,c); } if(spfa()){ cout<<"Yes"<<endl; }else{ cout<<"No"<<endl; } system("pause"); return 0; }
求逆元 1.快速幂相对第二种慢一些
题目链接—https://www.luogu.com.cn/problem/P3811
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include<bits/stdc++.h> using namespace std; typedef long long ll; ll test(ll x,ll y,ll z) { ll sum=1; ll ans=x%z; while(y) { if(y&1) { sum=(sum*ans)%z; } ans=(ans*ans)%z; y>>=1; } return sum; } int main() { freopen("a.in", "r", stdin); freopen("b.out", "w", stdout); ll n,mod; cin>>n>>mod; for(ll i=1;i<=n;i++) { cout<<test(i,mod-2,mod)<<endl; } return 0; }
2.线性时间复杂度 这里主要是最好用节省时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include<cstdio> using namespace std; long long inv[3000010]; int main() { long long n,mod; scanf("%lld%lld",&n,&mod); printf("1\n"); inv[1]=1; for(int i=2;i<=n;i++) { inv[i]=mod-(mod/i)*inv[mod%i]%mod; printf("%lld\n",inv[i]); } return 0; }
线段树 1.最简单的 题目在下面 https://img-blog.csdnimg.cn/2020021217471941.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTY5Nzc3NA==,size_16,color_FFFFFF,t_70
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6; ll arr[maxn]; struct st { ll l; ll r; ll sum; } tree[maxn]; void build(int i, int l, int r) { tree[i].l = l; tree[i].r = r; if (l == r) { tree[i].sum = arr[l]; return; } ll mid = (l + r) >> 1; build(i * 2, l, mid); build(i * 2 + 1, mid + 1, r); tree[i].sum = tree[i * 2].sum * tree[i * 2 + 1].sum; } ll search(ll i, ll l, ll r) { if (tree[i].l >= l && tree[i].r <= r) return tree[i].sum; ll res = 1; if (tree[i * 2].r >= l) { res = (res * search(i * 2, l, r)); } if (tree[i * 2 + 1].l <= r) { res = (res * search(i * 2 + 1, l, r)); } return res; } int main() { ll n, k; cin >> n >> k; for (int i = 1; i <= n; i++) { cin >> arr[i]; } build(1, 1, n); ll ans = 0; for (int i = 1; i <= n - k; i++) { ans = max(ans, search(1, i, i + k - 1)); } cout << ans << endl; return 0; }
2.简单的模板 随意加和查询 https://www.luogu.com.cn/problem/P3372
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 #include <bits/stdc++.h> using namespace std; const int maxn = 10e6; typedef long long ll; ll arr[maxn]; struct st { ll l, r, sum, lz; } tree[maxn]; void build(ll i, ll l, ll r, ll *arr) { tree[i].l = l; tree[i].r = r; tree[i].lz = 0; if (l == r) { tree[i].sum = arr[l]; return ; } ll mid = (l + r) >> 1; build(i * 2, l, mid, arr); build(i * 2 + 1, mid + 1, r, arr); tree[i].sum = tree[i * 2].sum + tree[i * 2 + 1].sum; return; } <!-- 主要作用是不让往下遍历(标记),直接存这里就好,之后(搜索查找的时候再传下去)或者再次添加的时候传下去,保证结果正确 --> void push_down(ll i) { if (tree[i].lz != 0) { tree[i * 2].lz += tree[i].lz; tree[i * 2 + 1].lz += tree[i].lz; int mid = (tree[i].l + tree[i].r) / 2; tree[i * 2].sum += tree[i].lz * (mid - tree[i * 2].l + 1); tree[i * 2 + 1].sum += tree[i].lz * (tree[i * 2+1].r - mid); tree[i].lz = 0; } return; } void add(ll i, ll l, ll r, ll k) { if (tree[i].l >= l && tree[i].r <= r) { tree[i].sum += k * (tree[i].r - tree[i].l + 1); tree[i].lz += k; return; } push_down(i); if (tree[i * 2].r >= l) { add(i * 2, l, r, k); } if (tree[i * 2 + 1].l <= r) { add(i * 2 + 1, l, r, k); } tree[i].sum = tree[i * 2].sum + tree[i * 2 + 1].sum; return; } ll searchs(ll i, ll l, ll r) { if (tree[i].l >= l && tree[i].r <= r) { return tree[i].sum; } push_down(i); ll num = 0; if (tree[i * 2].r >= l) { num += searchs(i * 2, l, r); } if (tree[i * 2 + 1].l <= r) { num += searchs(i * 2 + 1, l, r); } return num; } int main() { freopen("a.in", "r", stdin); freopen("b.out", "w", stdout); ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); ll n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> arr[i]; } build(1, 1, n, arr); for (int i = 1; i <= m; i++) { int temp; cin >> temp; if (temp == 1) { ll a, b, c; cin >> a >> b >> c; add(1, a, b, c); } else { ll a, b; cin >> a >> b; cout << searchs(1, a, b)<<endl; } } return 0; }
最小生成树 https://blog.csdn.net/qq_43619271/article/details/109091314?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165121095416782184637180%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165121095416782184637180&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_positive~default-1-109091314.nonecase&utm_term=%E6%9C%80%E5%B0%8F%E7%94%9F%E6%88%90%E6%A0%91&spm=1018.2226.3001.4450
prim 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <bits/stdc++.h> using namespace std; const int maxn = 505; int INF = 0x3f3f3f3f; int edge[maxn][maxn]; int dist[maxn], vis[maxn]; int n, m, u, v, w; long long sum = 0; long long prime(int pos) { dist[pos] = 0; for (int i = 1; i <= n; i++) { int cur = -1; for (int j = 1; j <= n; j++) { if (!vis[j] && (cur == -1 || dist[j] < dist[cur])) { cur = j; } } if (dist[cur] >= INF) return INF; sum += dist[cur]; vis[cur] = 1; for (int k = 1; k <= n; k++) { if (!vis[k]) dist[k] = min(dist[k], edge[cur][k]); } } return sum; } int main() { freopen("a.in", "r", stdin); freopen("b.out", "w", stdout); cin >> n >> m; memset(dist, 0x3f, sizeof(dist)); memset(edge, 0x3f, sizeof(edge)); for (int i = 1; i <= m; i++) { cin >> u >> v >> w; edge[u][v] = min(edge[u][v],w); edge[v][u] = min(edge[v][u],w); } long long value = prime(1); if (value >= INF) { cout << "impossible" << endl; } else { cout << value << endl; } return 0; }
Kruskal算法求最小生成树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <bits/stdc++.h> using namespace std; const int maxn = 10e6; struct st { int x; int y; int z; } edge[maxn]; int fa[maxn]; long long sum=0; int find1(int key) { if (fa[key] == key) { return key; } else return fa[key] = find1(fa[key]); } bool cmp(st s1, st s2) { return s1.z < s2.z; } int main() { long long n, m; cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> edge[i].x >> edge[i].y >> edge[i].z; } for (int i = 0; i <= n; i++) { fa[i] = i; } sort(edge+1, edge + m+1, cmp); for (int i = 1; i <= m; i++) { int x = find1(edge[i].x); int y = find1(edge[i].y); if (x == y) { continue; } fa[x] = y; sum += edge[i].z; } int ans = 0; for (int i = 1; i <= n; i++) { if (i == fa[i]) { ans++; } } if (ans > 1) cout << "impossible" << endl; else cout << sum; return 0; }
二分图匹配 染色法判定二分图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <bits/stdc++.h> using namespace std; const int N = 1e6; int h[N], e[N], ne[N], idx; int color[N]; void add(int u, int v) { e[idx] = v; ne[idx] = h[u]; h[u] = idx++; } bool dfs(int i, int k) { color[i] = k; for (int j = h[i]; j != -1; j = ne[j]) { int b = e[j]; if (!color[b]) { if (!dfs(b, 3 - k)) return false; } else if (color[b] && color[b] != 3 - k) { return false; } } return true; } int main() { freopen("a.in", "r", stdin); freopen("b.out", "w", stdout); memset(h, -1, sizeof(h)); int n, m; cin >> n >> m; int u, v; for (int i = 1; i <= m; i++) { cin >> u >> v; add(u, v); add(v, u); } for (int i = 0; i < n; i++) { if (!color[i]) { if (!dfs(i, 1)) { cout << "NO" << endl; return 0; } } } cout << "YES" << endl; return 0; }
辛普森积分 https://blog.csdn.net/weixin_30444105/article/details/95306900?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165132001016782390558168%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165132001016782390558168&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-95306900.142^v9^pc_search_result_control_group,157^v4^control&utm_term=辛普森积分&spm=1018.2226.3001.4187
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include <bits/stdc++.h> using namespace std;const double esp = 1e7 ;typedef double db;double a, b, c, d, L, R;db f (db x) { return (c * x + d) / (a * x + b); } db sim (db l, db r) { return (f (l)+f (r)+4 *f ((l+r)/2 ))*(r-l)/6 ; } double asr (db L, db R,db esp ,db val) { db mid=(L+R)/2 ; db lval=sim (L,mid); db rval=sim (mid,R); if (fabs (lval+rval-val)<=15 *esp){return lval+rval+(lval+rval-val)/15 ;} return asr (L,mid,esp/2 ,lval)+asr (mid,R,esp/2 ,rval); } double asme (db L, db R, db esp) { return asr (L, R, esp, sim (L, R)); } int main () { cin >> a >> b >> c >> d >> L >> R; cout <<fixed<<setprecision (6 )<< asme (L, R, esp); return 0 ; }
计算几何 *面积公式* double area(BWE A,BWE B,BWE C)
{
//用于计算三角形面积的函数(直接套用题目中的公式)
return abs(A.x*(B.y-C.y)+B.x*(C.y-A.y)+C.x*(A.y-B.y))/2;
}
求两点之间的整数点个数 gcd(abs(a1-a2), abs(b1-b2));
皮克定理 其中a表示多边形内部的点数(就是题目中要求的答案),b表示多边形恰好落在边界上的点数,s表示多边形的面积。 易知,a=S-b/2+1
旋转点 我们可以这样认为:对于任意点A(x,y),A非原点,绕原点旋转θ角后点的坐标为: (xcosθ- y * sinθ, ycosθ + x * sinθ)、 如果不绕原点的话可以直接加减(xx,yy); (xcosθ- y * sinθ+xx, ycosθ + x * sinθ+yy)、 绕其他(x2,y2)点旋转 ((x-x2)*cosθ- (y-y2) * sinθ+x2, (y-y2)*cosθ + (x-x2) * sinθ+y2)
求凸包模板题 https://www.luogu.com.cn/problem/P2742
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespace std;int n, num = 1 ;struct ben { double x, y; } p[100005 ], s[100005 ]; double check (ben a1, ben a2, ben b1, ben b2) { return (a2.x - a1.x) * (b2.y - b1.y) - (b2.x - b1.x) * (a2.y - a1.y); } double d (ben p1, ben p2) { return sqrt ((p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x)); } bool cmp (ben lhs, ben rhs) { if (check (p[1 ], lhs, p[1 ], rhs) < 0 ) return false ; if (check (p[1 ], lhs, p[1 ], rhs) > 0 ) return true ; return d (p[1 ], lhs) < d (p[1 ], rhs); } void add (double ll, double ff) { double mid; p[num].x = ll, p[num].y = ff; if (p[num].y < p[1 ].y || (p[num].y == p[1 ].y && p[num].x < p[1 ].x)) { swap (p[num], p[1 ]); } num++; return ; } int main () { scanf ("%d" , &n); double mid, ll, ff; for (int i = 1 ; i <= n; i++) { scanf ("%lf%lf" , &ll, &ff); add (ll, ff); } sort (p + 2 , p + 1 + n, cmp); s[1 ] = p[1 ]; int cnt = 1 ; for (int i = 2 ; i <= num - 1 ; i++) { while (cnt > 1 && check (s[cnt - 1 ], s[cnt], s[cnt], p[i]) < 0 ) cnt--; cnt++; s[cnt] = p[i]; } s[cnt + 1 ] = p[1 ]; double ans = 0 ; for (int i = 1 ; i <= cnt; i++) ans += d (s[i], s[i + 1 ]); printf ("%.2lf\n" , ans); return 0 ; }
求凸包 难一点 https://www.luogu.com.cn/problem/P3829
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespace std;#define eps 1e-12 int n, num = 1 ;double a, b, r;struct ben { double x, y; } p[1000005 ], s[1000005 ]; double check (ben a1, ben a2, ben b1, ben b2) { return (a2.x - a1.x) * (b2.y - b1.y) - (b2.x - b1.x) * (a2.y - a1.y); } double d (ben p1, ben p2) { return sqrt ((p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x)); } bool cmp (ben lhs, ben rhs) { if (check (p[1 ], lhs, p[1 ], rhs) < 0 ) return false ; if (check (p[1 ], lhs, p[1 ], rhs) > 0 ) return true ; return d (p[1 ], lhs) < d (p[1 ], rhs); } void add (double ll, double ff) { double mid; p[num].x = ll, p[num].y = ff; if (p[num].y < p[1 ].y || (p[num].y == p[1 ].y && p[num].x < p[1 ].x)) { swap (p[num], p[1 ]); } num++; return ; } int main () { freopen ("a.in" , "r" , stdin); freopen ("b.out" , "w" , stdout); scanf ("%d%lf%lf%lf" , &n, &b, &a, &r); a = a / 2.0 ; b = b / 2.0 ; double mid, xx, yx, th; for (int i = 1 ; i <= n; i++) { scanf ("%lf%lf%lf" , &xx, &yx, &th); xx += eps; yx += eps; th += eps; double s1 = sin (th); double c1 = cos (th); add ((a - r) * c1 - (b - r) * s1 + xx, (b - r) * c1 + (a - r) * s1 + yx); add (-(a - r) * c1 - (b - r) * s1 + xx, (b - r) * c1 - (a - r) * s1 + yx); add ((a - r) * c1 + (b - r) * s1 + xx, -(b - r) * c1 + (a - r) * s1 + yx); add (-(a - r) * c1 + (b - r) * s1 + xx, -(b - r) * c1 - (a - r) * s1 + yx); } sort (p + 2 , p + num, cmp); s[1 ] = p[1 ]; int cnt = 1 ; for (int i = 2 ; i <= num - 1 ; i++) { while (cnt > 1 && check (s[cnt - 1 ], s[cnt], s[cnt], p[i]) <= 0 ) cnt--; cnt++; s[cnt] = p[i]; } s[cnt + 1 ] = p[1 ]; double ans = 0 ; for (int i = 1 ; i <= cnt; i++) ans += d (s[i], s[i + 1 ]); printf ("%.2lf\n" , ans + 3.141592653589793 * 2 * r); return 0 ; }
旋转卡壳 https://www.luogu.com.cn/problem/P1452
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 #include <bits/stdc++.h> using namespace std;int n, num = 1 ;int v = 2 ;double ans = 0 ;struct ben { double x, y; } p[100005 ], s[100005 ]; double check (ben u1, ben u2, ben v1, ben v2) { return (u2.x - u1.x) * (v2.y - v1.y) - (u2.y - u1.y) * (v2.x - v1.x); } double d (ben p1, ben p2) { return (p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x); } bool cmp (ben lhs, ben rhs) { if (check (p[1 ], lhs, p[1 ], rhs) < 0 ) return false ; if (check (p[1 ], lhs, p[1 ], rhs) > 0 ) return true ; return d (p[1 ], lhs) < d (p[1 ], rhs); } void add (double ll, double ff) { double mid; p[num].x = ll, p[num].y = ff; if (p[num].y < p[1 ].y || (p[num].y == p[1 ].y && p[num].x < p[1 ].x)) { swap (p[num], p[1 ]); } num++; return ; } int main () { scanf ("%d" , &n); double mid, ll, ff; for (int i = 1 ; i <= n; i++) { scanf ("%lf%lf" , &ll, &ff); add (ll, ff); } sort (p + 2 , p + num, cmp); s[1 ] = p[1 ]; int cnt = 1 ; for (int i = 2 ; i <= num - 1 ; i++) { while (cnt > 1 && check (s[cnt - 1 ], s[cnt], s[cnt], p[i]) <= 0 ) cnt--; cnt++; s[cnt] = p[i]; } s[cnt + 1 ] = p[1 ]; if (cnt == 1 ) return 0 ; if (cnt == 2 ) { cout << fixed << setprecision (0 ) << d (s[1 ], s[2 ]) << endl; return 0 ; } for (int u = 1 ; u <= cnt; ++u) { while (check (s[u], s[u + 1 ], s[u + 1 ], s[v]) <= check (s[u], s[u + 1 ], s[u + 1 ], s[v + 1 ])) { v = v == cnt ? 1 : v + 1 ; } ans = max (ans, max (d (s[u], s[v]), d (s[u + 1 ], s[v]))); } printf ("%.0lf\n" , ans); return 0 ; }
kmp ****推荐学习网址****:https://www.cnblogs.com/-citywall123/p/11688576.html;
****注意****:
*在有符号整型和无符号整型的比较中,自动将有符号整型数转换为无符号整型。*
C++方法:
不要尝试理解kmp算法,与递归同理
下面是求****Next****数组的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <iostream> #include <string> using namespace std;const int n = 1008 ;string s; int Next[n];void aa () { Next[0 ] = -1 ; int i = 0 ; int j = -1 ; while (i <= s.length ()) { if (j == -1 || s[i] == s[j]) { Next[++i] = ++j; } else { j = Next[j]; } } } int main () { cin >> s; aa (); for (int i = 0 ; i < s.length (); i++) { cout << " " << Next[i] << " " ; } return 0 ; }
****下面是全的代码****:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 #include <iostream> #include <cstring> #include <string> using namespace std;const int n = 1e6 + 10 ;int next1[n];string re; string te; int re1, te1;void get_ne () { int i = 0 ; int j = -1 ; next1[0 ] = -1 ; while (i < te1) { if (j == -1 || te[i] == te[j]) { next1[++i] = ++j; } else { j = next1[j]; } } } int get_piace () { int i = 0 ; int j = 0 ; while (i < re1 && j < te1) { if (j == -1 || te[j] == re[i]) { i++; j++; } else { j = next1[j]; } } if (j >= te1) { return i - te1 + 1 ; } else { return -1 ; } } int main () { cin >> re >> te; re1 = re.size (); te1 = te.length (); get_ne (); cout << "查找到的位置初始是:" << get_piace () << endl return 0 ; }
最长上升子序列 LIS 1.dp 最长联通串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <bits/stdc++.h> using namespace std;int va[40 ][40 ];int a[30 ];int b[30 ];int dp[30 ];void dfs (int num) { if (b[num]) dfs (b[num]); cout<<num<<" " ; } int main () { freopen ("a.in" ,"r" ,stdin); freopen ("b.out" ,"w" ,stdout); int n; cin>>n; for (int i=1 ;i<=n;i++) { cin>>a[i]; } for (int i=1 ;i<=n-1 ;i++) { for (int j=i+1 ;j<=n;j++) { int temp; cin>>temp; if (temp) { va[i][j]=1 ; } } } int ans=0 ,pos=0 ; dp[1 ]=a[1 ]; for (int i=2 ;i<=n;i++) { dp[i]=a[i]; for (int j=i-1 ;j>=1 ;j--) { if (va[j][i]&&dp[i]<dp[j]+a[i]) { dp[i]=dp[j]+a[i]; b[i]=j; } } if (ans<dp[i]) { ans=dp[i]; pos=i; } } dfs (pos); cout<<endl<<ans; return 0 ; }
2.二分实现时间更短 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream> #include <cstdio> #include <algorithm> using namespace std;const int maxn = 1e5 + 5 ;int a[maxn], f[maxn];int cnt;inline int find (int x) { int l = 1 , r = cnt; while (l < r) { int mid = l + r >> 1 ; if (f[mid] >= x) r = mid; else l = mid + 1 ; } return l; } int main (void ) { int n; scanf ("%d" , &n); for (int i = 1 ; i <= n; i ++) scanf ("%d" , &a[i]); f[++cnt] = a[1 ]; for (int i = 2 ; i <= n; i ++) if (a[i] > f[cnt]) f[ ++ cnt] = a[i]; else { int tmp = find (a[i]); f[tmp] = a[i]; } printf ("%d\n" , cnt); return 0 ; }
LCS最长公共子序列 相当于用数组映射让第一个数组单调递增,之后数组映射获得在此情况下的另一个数组,最后要求的结果就变成了lis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <bits/stdc++.h> using namespace std;const int N=1e6 ;int a[N],b[N],f[N],mp[N];int main () { freopen ("a.in" ,"r" ,stdin); freopen ("b.out" ,"w" ,stdout); int n; cin>>n; for (int i=1 ;i<=n;i++) { cin>>a[i]; mp[a[i]]=i; } for (int i=1 ;i<=n;i++) { cin>>b[i]; f[i]=0x3f3f3f3f ; } f[0 ]=0 ; int len=0 ; for (int i=1 ;i<=n;i++) { if (mp[b[i]]>f[len]) { f[++len]=mp[b[i]]; }else { *lower_bound (f,f+len,mp[b[i]])=mp[b[i]]; } } cout<<len<<endl; return 0 ; }