#include<iostream> #include<cstdio> usingnamespace std; constint N = 1000010; int q[N]; voidquick_sort(int* q, int l, int r) { if (l >= r) return; int x = q[l + (r - l) / 2], i = l - 1, j = r + 1; while (i < j) { while (q[++i] < x); //do i++; while (q[i] < x); while (q[--j] > x); //do j--; while (q[j] > x); if (i < j) swap(q[i], q[j]); } quick_sort(q, l, j); quick_sort(q, j + 1, r); }
intmain() { int n = 0; scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d", &q[i]); quick_sort(q, 0, n-1); for(int i = 0; i < n; i++) printf("%d ", q[i]); return0; }
#include<iostream> #include<cstdio> #include<vector> #include<string> usingnamespace std; vector<int> Add(vector<int>& A, vector<int>& B) { vector<int> C; int t = 0; for (int i = 0; i < A.size() || i < B.size(); i++) { if (i < A.size()) t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; } if (t) C.push_back(1); return C; } intmain() { string a, b; vector<int> A, B; cin >> a >> b; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0'); vector<int> C = Add(A, B); for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); return0; }
#include<iostream> #include<vector> #include<string> #include<cstdio> usingnamespace std; boolcmp(vector<int>& A, vector<int>& B) { if (A.size() != B.size()) return A.size() > B.size(); for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] > B[i]; } returntrue; } vector<int> Sub(vector<int>& A, vector<int>& B) { vector<int> C; for (int i = 0, t = 0; i < A.size(); i++) { t = A[i] - t; if (i < B.size()) t -= B[i]; C.push_back((t + 10) % 10); if (t < 0) t = 1; else t = 0; }
intmain() { string a, b; vector<int> A, B; cin >> a >> b; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0'); if (cmp(A, B)) { vector<int> C = Sub(A, B); for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); } else { printf("-"); vector<int> C = Sub(B, A); for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]); } return0; }
#include<iostream> #include<cstdio> usingnamespace std; constint N = 1e6 + 10; int a[N], s[N]; intmain() { int n = 0; cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; int res = 0; for (int i = 0, j = 0; i < n; i++) { s[a[i]]++; while (s[a[i]] > 1) { s[a[j]]--; j++; } res = max(res, i - j + 1); } cout << res << endl; return0; }
#include<iostream> #include<cstdio> #include<algorithm> usingnamespace std; constint N = 1e5 + 10; int a[N], b[N]; intmain() { int n = 0, m = 0, x = 0; scanf("%d%d%d", &n, &m, &x); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < m; i++) scanf("%d", &b[i]); for (int i = 0, j = m - 1; i < n; i++) { while (j >= 0 && a[i] + b[j] > x) j--; if (a[i] + b[j] == x) { printf("%d %d\n", i, j); break; }
#include<iostream> #include<cstdio> usingnamespace std; constint N = 100010; int a[N], b[N]; intmain() { int n = 0, m = 0; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < m; i++) scanf("%d", &b[i]); int i = 0; for (int j = 0; j < m; j++) { if (i < n && a[i] == b[j]) i++; } if (i == n) printf("Yes\n"); elseprintf("No\n"); return0; }
#include<iostream> #include<cmath> usingnamespace std; intlowbit(int x) { return x & -x; } intmain() { int n = 0; cin >> n; while (n--) { int x = 0; cin >> x; int res = 0; while (x) { x -= lowbit(x); res++; } cout << res << " "; } return0; }
#include<iostream> #include<algorithm> #include<vector> usingnamespace std; constint N = 300010; typedef pair<int, int> PII; int a[N], s[N]; vector<int> alls; vector<PII> add, query; intfind(int x) { int l = 0, r = alls.size() - 1; while (l < r) { int mid = l + r >> 1; if (alls[mid] >= x) r = mid; else l = mid + 1; } return l + 1; //前缀和从1开始,因此这里返回下标也从1开始吧 } intmain() { int n, m; cin >> n >> m; while (n--) { int b, c; scanf("%d%d", &b, &c); add.push_back({ b, c }); alls.push_back(b); } while (m--) { int l, r; scanf("%d%d", &l, &r);
query.push_back({ l, r });
alls.push_back(l); alls.push_back(r); }
sort(alls.begin(), alls.end()); //排序 alls.erase(unique(alls.begin(), alls.end()), alls.end()); //去重 //处理插入 for (auto item : add) { int i = find(item.first); a[i] += item.second; } //预处理前缀和 for (int i = 1; i <= alls.size(); i++) s[i] = s[i - 1] + a[i];
//处理询问 for (auto item : query) { int l = find(item.first), r = find(item.second); printf("%d\n", s[r] - s[l - 1]); } return0; }
voideval()//求值 { int a = num.top();//第二个操作数 num.pop(); int b = num.top();//第一个操作数 num.pop(); char p = op.top();//运算符 op.pop(); int r = 0;//结果 //计算结果 if (p == '+') r = b + a; if (p == '-') r = b - a; if (p == '*') r = b * a; if (p == '/') r = b / a;
num.push(r);//结果入栈 }
intmain() { string s;//读入表达式 cin >> s;
for (int i = 0; i < s.size(); i++) { if (isdigit(s[i]))//数字入栈 { int x = 0, j = i;//计算数字 while (j < s.size() && isdigit(s[j])) { x = x * 10 + s[j] - '0'; j++; } num.push(x);//数字入栈 i = j - 1; } //左括号无优先级,直接入栈 elseif (s[i] == '(')//左括号入栈 { op.push(s[i]); } //括号特殊,遇到左括号直接入栈,遇到右括号计算括号里面的 elseif (s[i] == ')')//右括号 { while (op.top() != '(')//一直计算到左括号 eval(); op.pop();//左括号出栈 } else { while (op.size() && h[op.top()] >= h[s[i]])//待入栈运算符优先级低,则先计算 eval(); op.push(s[i]);//操作符入栈 } } while (op.size()) eval();//剩余的进行计算 cout << num.top() << endl;//输出结果 return0; }
#include<iostream> usingnamespace std; constint N = 100010; int son[N][26], cnt[N], idx; char str[N]; voidinsert(char str[]) { int p = 0; for (int i = 0; str[i]; i++) { int u = str[i] - 'a'; if (!son[p][u]) son[p][u] = ++idx; p = son[p][u]; } cnt[p]++; } intquery(char str[]) { int p = 0; for (int i = 0; str[i]; i++) { int u = str[i] - 'a'; if (!son[p][u]) return0; p = son[p][u]; } return cnt[p]; }
intmain() { int n; scanf("%d", &n); while (n--) { char op[2]; scanf("%s%s", op, str); if (op[0] == 'I') insert(str); elseprintf("%d\n", query(str)); } return0; }
#include<iostream> #include<algorithm> usingnamespace std; constint N = 100010, M = 3000000; int n; int son[M][2], idx; int a[N];
voidinsert(int x) { int p = 0; for (int i = 30; i >= 0; i--) { int& s = son[p][x >> i & 1]; if (!s) s = ++idx; //创建新节点 p = s; } }
intquery(int x) { int res = 0, p = 0; for (int i = 30; i >= 0; i--) { int s = x >> i & 1; if (son[p][!s]) { res += 1 << i; p = son[p][!s]; } else p = son[p][s]; } return res; }
intmain() { cin >> n; for (int i = 0; i < n; ++i) { cin >> a[i]; insert(a[i]); } int res = 0; for (int i = 0; i < n; ++i) res = max(res, query(a[i])); cout << res << endl; return0; }
#include<iostream> #include<cstdio> usingnamespace std; constint N = 100010; int n, m; int p[N]; intfind(int x)//返回x的祖宗节点 + 路径压缩 { if (p[x] != x) p[x] = find(p[x]); return p[x]; }
intmain() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) p[i] = i; while (m--) { char op[2]; int a, b; scanf("%s%d%d", op, &a, &b); if (op[0] == 'M') p[find(a)] = find(b); else { if (find(a) == find(b)) puts("Yes"); elseputs("No"); } } return0; }
#include<iostream> #include<cstdio> usingnamespace std; constint N = 100010; int n, m; int p[N], t_size[N]; intfind(int x)//返回x的祖宗节点 + 路径压缩 { if (p[x] != x) p[x] = find(p[x]); return p[x]; }
intmain() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { p[i] = i; t_size[i] = 1; } while (m--) { char op[5]; int a, b; scanf("%s", op); if (op[0] == 'C') { scanf("%d%d", &a, &b); if (find(a) == find(b)) continue; t_size[find(b)] += t_size[find(a)]; p[find(a)] = find(b); } elseif (op[1] == '1') { scanf("%d%d", &a, &b); if (find(a) == find(b)) puts("Yes"); elseputs("No"); } else { scanf("%d", &a); printf("%d\n", t_size[find(a)]); } } return0; }
#include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<string> usingnamespace std; constint N = 100010; int n, m; int h[N], cnt;
voiddown(int u) { int t = u; if (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2; if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 1; if (u != t) { swap(h[u], h[t]); down(t); } } intmain() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%d", &h[i]); cnt = n; for (int i = n / 2; i; i--) down(i); while (m--) { printf("%d ", h[1]); h[1] = h[cnt]; cnt--; down(1); } return0; }
#include<iostream> #include<algorithm> usingnamespace std; constint N = 1e5 + 10; int h[N]; //堆 int ph[N]; //存放第k个插入点的下标 int hp[N]; //存放堆中点的插入次序 int cur_size; //size 记录的是堆当前的数据多少
intbfs(string start) { string end = "12345678x"; queue<string> q; unordered_map<string, int> d; q.push(start); d[start] = 0; int dx[4] = { -1, 0, 1, 0 }, dy[4] = { 0, 1, 0, -1 }; while (q.size()) { string t = q.front(); q.pop(); int distance = d[t]; if (t == end) return distance; //状态转移 int k = t.find('x'); int x = k / 3, y = k % 3;
for (int i = 0; i < 4; i++) { int a = x + dx[i], b = y + dy[i]; if (a >= 0 && a < 3 && b >= 0 && b < 3) { swap(t[k], t[a * 3 + b]); if (!d.count(t)) { d[t] = distance + 1; q.push(t); } swap(t[k], t[a * 3 + b]); } } } return-1; }
constint N = 1e5 + 10; //数据范围是10的5次方 constint M = 2 * N; //以有向图的格式存储无向图,所以每个节点至多对应2n-2条边
int h[N]; //邻接表存储树,有n个节点,所以需要n个队列头节点 int e[M]; //存储元素 int ne[M]; //存储列表的next值 int idx; //单链表指针 int n; //题目所给的输入,n个节点 int ans = N; //表示重心的所有的子树中,最大的子树的结点数目
bool st[N]; //记录节点是否被访问过,访问过则标记为true
//a所对应的单链表中插入b a作为根 voidadd(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
// dfs 框架 /* void dfs(int u) { st[u]=true; // 标记一下,记录为已经被搜索过了,下面进行搜索过程 for(int i=h[u];i!=-1;i=ne[i]) { int j=e[i]; if(!st[j]) { dfs(j); } } } */ //返回以u为根的子树中节点的个数,包括u节点 intdfs(int u) { int res = 0; //存储 删掉某个节点之后,最大的连通子图节点数 st[u] = true; //标记访问过u节点 int sum = 1; //存储 以u为根的树 的节点数, 包括u,如图中的4号节点
//访问u的每个子节点 for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; //因为每个节点的编号都是不一样的,所以 用编号为下标 来标记是否被访问过 if (!st[j]) { int s = dfs(j); // u节点的单棵子树节点数 如图中的size值 res = max(res, s); // 记录最大联通子图的节点数 sum += s; //以j为根的树 的节点数 } }
//n-sum 如图中的n-size值,不包括根节点4; res = max(res, n - sum); // 选择u节点为重心,最大的 连通子图节点数 ans = min(res, ans); //遍历过的假设重心中,最小的最大联通子图的 节点数 return sum; }
// 题目接下来会输入,n-1行数据, // 树中是不存在环的,对于有n个节点的树,必定是n-1条边 for (int i = 0; i < n - 1; i++) { int a, b; cin >> a >> b; add(a, b), add(b, a); //无向图 } dfs(1); //可以任意选定一个节点开始 u<=n cout << ans << endl; return0; }
#include<iostream> #include<cstring> #include<algorithm> usingnamespace std; constint N = 100010; int h[N], e[N], ne[N], idx; int n, m; int q[N], d[N];//q表示队列,d表示点的入度
voidadd(int a, int b) { e[idx] = b; ne[idx] = h[a]; h[a] = idx++; }
booltopsort() { int hh = 0, tt = -1; for (int i = 1; i <= n; i++) if (!d[i]) q[++tt] = i;//将入度为零的点入队 while (hh <= tt) { int t = q[hh++]; for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; d[j]--;//删除点t指向点j的边 if (d[j] == 0)//如果点j的入度为零了,就将点j入队 q[++tt] = j; } } return tt == n - 1; //表示如果n个点都入队了话,那么该图为拓扑图,返回true,否则返回false }
intmain() { cin >> n >> m; memset(h, -1, sizeof(h));//如果程序时间溢出,就是没有加上这一句 for (int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); add(a, b);//因为是a指向b,所以b点的入度要加1 d[b]++; } if (topsort()) { for (int i = 0; i < n; i++) printf("%d ", q[i]); //经上方循环可以发现队列中的点的次序就是拓扑序列 //注:拓扑序列的答案并不唯一,可以从解析中找到解释 puts(""); } elseputs("-1"); return0; }
#include<iostream> #include<algorithm> #include<cstring> usingnamespace std; constint N = 510; int g[N][N]; //为稠密阵所以用邻接矩阵存储 int dist[N]; //用于记录每一个点距离第一个点的距离 bool st[N]; //用于记录该点的最短距离是否已经确定 int n, m;
intDijkstra() { memset(dist, 0x3f, sizeof dist); //初始化距离 0x3f代表无限大 dist[1] = 0; //第一个点到自身的距离为0 for (int i = 0; i < n; i++) //有n个点所以要进行n次 迭代 { int t = -1; //t存储当前访问的点 for (int j = 1; j <= n; j++) //这里的j代表的是从1号点开始 if (!st[j] && (t == -1 || dist[t] > dist[j])) t = j; st[t] = true; for (int j = 1; j <= n; j++) //依次更新每个点所到相邻的点路径值 dist[j] = min(dist[j], dist[t] + g[t][j]); }
if (dist[n] == 0x3f3f3f3f) return-1; //如果第n个点路径为无穷大即不存在最低路径 return dist[n]; } intmain() { cin >> n >> m; memset(g, 0x3f, sizeof g); //初始化图 因为是求最短路径 //所以每个点初始为无限大 while (m--) { int x, y, z; cin >> x >> y >> z; g[x][y] = min(g[x][y], z); //如果发生重边的情况则保留最短的一条边 } cout << Dijkstra() << endl; return0; }
#include<iostream> #include<vector> #include<queue> #include<memory.h> usingnamespace std; typedef pair<int, int> PII; constint N = 100010; vector<vector<pair<int, int>>> gra; int dist[N]; int st[N]; int n, m; intsolve() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; //这里是距离在前 节点号在后 priority_queue<PII, vector<PII>, greater<PII>> heap; heap.push({ 0, 1 }); // first存储距离,second存储节点编号 while (heap.size()) { auto t = heap.top(); heap.pop(); int node = t.second; int distance = t.first; if (st[node]) continue; st[node] = true; //查看每个出边 for (int i = 0; i < gra[node].size(); i++) { int newnode = gra[node][i].first; int len = gra[node][i].second; if (dist[newnode] > dist[node] + len) { dist[newnode] = dist[node] + len; heap.push({ dist[newnode],newnode }); } } } if (dist[n] == 0x3f3f3f3f) return-1; return dist[n]; }
intmain() { //cin >> n >> m; scanf("%d %d", &n, &m); gra.resize(n + 1);
for (int i = 0; i < m; i++) { int a, b, c; //cin >> a >> b >> c; scanf("%d %d %d", &a, &b, &c); //这里是 目的节点号在前 边长在后 gra[a].push_back({ b,c }); } printf("%d\n", solve()); return0; }
#include<iostream> #include<algorithm> #include<cstring> usingnamespace std; constint N = 100010; int dist[N], backup[N]; int k, n, m; structedge { int a; int b; int w; }edge[N]; intbellman_ford() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; for (int i = 1; i <= k; i++) { memcpy(backup, dist, sizeof dist); for (int j = 1; j <= m; j++) { int a = edge[j].a, b = edge[j].b, w = edge[j].w; dist[b] = min(dist[b], backup[a] + w); } } return dist[n]; } intmain() { cin >> n >> m >> k; for (int i = 1; i <= m; i++) { int a, b, c; cin >> a >> b >> c; edge[i].a = a, edge[i].b = b, edge[i].w = c; } int t = bellman_ford(); if (t >= 0x3f3f3f3f / 2)puts("impossible"); else cout << t << endl; }
#include<cstring> #include<iostream> #include<algorithm> #include<queue> usingnamespace std; constint N = 100010; int n, m; int h[N], w[N], e[N], ne[N], idx; int dist[N]; //储存当前点到起点的距离 bool st[N]; //当前点是否在队列当中,防止存重复的点
voidadd(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; }
intspfa() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; //起点距自己的距离为 0 queue<int> q; q.push(1); //起点加入队列 st[1] = true; //起点在队列里了 while (q.size()) //如果队列不空 { int t = q.front(); //取出队头 q.pop(); //删掉队头 st[t] = false;//这个点已经不在队列里边了 for (int i = h[t]; i != -1; i = ne[i]) //更新 t 的所有邻边 { int j = e[i]; //取出当前邻边的节点 if (dist[j] > dist[t] + w[i]) { dist[j] = dist[t] + w[i]; if (!st[j]) //如果 j 不在队列里边 { q.push(j); //加入队列 st[j] = true; //在队列里了 } } } } return dist[n]; }
intmain() { scanf("%d%d", &n, &m); memset(h, -1, sizeof h); while (m--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); } int t = spfa(); if (t == 0x3f3f3f3f) puts("impossible"); elseprintf("%d\n", t); return0; }
#include<iostream> #include<cstring> #include<algorithm> #include<queue> usingnamespace std; constint N = 1e5 + 10; int h[N], e[N], ne[N], w[N], idx; int n, m; int dis[N], cnt[N]; bool st[N];
voidadd(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; }
boolspfa() { memset(dis, 0x3f, sizeof(dis)); dis[1] = 0; queue<int> q; for (int i = 1; i <= n; i++) { st[i] = true; q.push(i); }
while (q.size()) { int t = q.front(); q.pop(); st[t] = false; for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; if (dis[j] > dis[t] + w[i]) { dis[j] = dis[t] + w[i]; cnt[j] = cnt[t] + 1;
if (cnt[j] >= n)returntrue; if (!st[j]) { q.push(j); st[j] = true; } } } } returnfalse; }
intmain() { 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())puts("Yes"); elseputs("No"); return0; }
while (!q.empty()) { auto t = q.top(); q.pop(); int ver = t.second, dst = t.first; if (vis[ver]) continue; vis[ver] = true, sum += dst, ++cnt;
for (int i = h[ver]; i != -1; i = ne[i]) { int j = e[i]; if (!vis[j]) { q.push({ w[i], j }); } } } if (cnt != n) return INF; return sum; }
intmain() { cin >> n >> m; memset(h, -1, sizeof h); for (int i = 0; i < m; ++i) { int a, b, w; cin >> a >> b >> w; add(a, b, w); add(b, a, w); } int t = Prim(); if (t == INF) cout << "impossible" << endl; else cout << t << endl; }
intKruskal() { int res = 0, cnt = 0;//res记录最小生成树的树边权重之和,cnt记录的是全部加入到树的集合中边的数量(可能有多个集合) for (int i = 0; i < m; i++) { int a = edges[i].a, b = edges[i].b, w = edges[i].w; if (find(a) != find(b)) /* 具体可以参考连通块中点的数量,如果a和b已经在一个集合当中了,说明这两个点已经被一种方式连接起来了, 如果加入a-b这条边,会导致集合中有环的生成,而树中不允许有环生成,所以一个连通块中的点的数量假设 为x,那么里面x个节点应该是被串联起来的,有x-1条边,所以只有当a,b所属的集合不同时,才能将a-b这条 边加入到总集合当中去 */ { p[find(a)] = p[find(b)];//将a,b所在的两个集合连接起来 cnt++;//因为加入的是a-b的这一条边,将a,b所在的两个集合连接之后,全部集合中的边数加1 res += w;//加入到集合中的边的权重之和 } } if (cnt == n - 1) return res;//可以生成最小生成树 elsereturn0x3f3f3f3f;//树中有n个节点便有n-1条边,如果cnt不等于n-1的话,说明无法生成有n个节点的树 }
intmain() { cin >> n >> m;
for (int i = 0; i < n; i++) p[i] = i;//初始化并查集
for (int i = 0; i < m; i++) { int a, b, w; scanf("%d%d%d", &a, &b, &w); edges[i] = { a,b,w }; } sort(edges, edges + m);//将边的权重按照大小一一排序 int t = Kruskal(); if (t == 0x3f3f3f3f) printf("impossible\n"); elseprintf("%d\n", t);
#include<iostream> #include<algorithm> #include<cstring> usingnamespace std; constint N = 1e5 + 10, M = 2e5 + 10;//由于是无向图, 顶点数最大是N,那么边数M最大是顶点数的2倍 int e[M], ne[M], h[N], idx; int st[N];
voidadd(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
booldfs(int u, int color) { st[u] = color; for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if (!st[j]) { if (!dfs(j, 3 - color)) returnfalse; } elseif (st[j] == color) returnfalse; } returntrue; }
intmain() { int n, m; scanf("%d%d", &n, &m);
memset(h, -1, sizeof h); while (m--) { int a, b; scanf("%d%d", &a, &b); add(a, b), add(b, a);//无向图,a->b, b->a }
bool flag = true; for (int i = 1; i <= n; i++) { if (!st[i]) { if (!dfs(i, 1)) { flag = false; break; } } }
#include<iostream> #include<cstring> usingnamespace std; constint N = 510, M = 100010; int n1, n2, m; int h[N], ne[M], e[M], idx; bool st[N]; int match[N];
voidadd(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
voidinit() { memset(h, -1, sizeof h); }
intfind(int x) { //遍历自己喜欢的女孩 for (int i = h[x]; i != -1; i = ne[i]) { int j = e[i]; if (!st[j])//如果在这一轮模拟匹配中,这个女孩尚未被预定 { st[j] = true;//那x就预定这个女孩了 //如果女孩j没有男朋友,或者她原来的男朋友能够预定其它喜欢的女孩。配对成功 if (!match[j] || find(match[j])) { match[j] = x; returntrue; } } } //自己中意的全部都被预定了。配对失败。 returnfalse; } intmain() { init(); cin >> n1 >> n2 >> m; while (m--) { int a, b; cin >> a >> b; add(a, b); } int res = 0; for (int i = 1; i <= n1; i++) { //因为每次模拟匹配的预定情况都是不一样的所以每轮模拟都要初始化 memset(st, false, sizeof st); if (find(i)) res++; } cout << res << endl; }
#include<iostream> #include<cstdio> #include<cmath> usingnamespace std; constint N = 1010; int a[N]; int n; boolisPrime(int n) { if (n < 2) returnfalse; for (int i = 2; i <= n / i; i++) { if (n % i == 0) returnfalse; } returntrue; } intmain() { cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; if (isPrime(a[i])) printf("Yes\n"); elseprintf("No\n"); } return0; }
#include<iostream> #include<cstdio> #include<algorithm> usingnamespace std; voiddivide(int n) { for (int i = 2; i <= n / i; i++) { if (n % i == 0) //i一定是质数 { int s = 0; while (n % i == 0) { n /= i; s++; } printf("%d %d\n", i, s); } } if (n > 1) printf("%d %d\n", n, 1); printf("\n"); }
intmain() { int n = 0; scanf("%d", &n); while (n--) { int x = 0; scanf("%d", &x); divide(x); } return0; }
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<algorithm> #include<unordered_map> usingnamespace std; typedeflonglong LL; constint mod = 1e9 + 7; intmain() { int n = 0; cin >> n; unordered_map<int, int> primes; while (n--) { int x = 0; cin >> x; for (int i = 2; i <= x / i; ++i) { while (x % i == 0) { x /= i; primes[i]++; } } if (x > 1) primes[x]++; }
LL res = 1; for (auto prime : primes) { res = res * (prime.second + 1) % mod; } cout << res << endl; return0; }
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<algorithm> #include<unordered_map> usingnamespace std; typedeflonglong LL; constint mod = 1e9 + 7; intmain() { int n = 0; cin >> n; unordered_map<int, int> primes; while (n--) { int x = 0; cin >> x; for (int i = 2; i <= x / i; ++i) { while (x % i == 0) { x /= i; primes[i]++;
} } if (x > 1) primes[x]++; }
LL res = 1; for (auto prime : primes) { int p = prime.first, a = prime.second; LL t = 1; while (a--) { t = (t * p + 1) % mod; } res = res * t % mod; } cout << res << endl; return0; }
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<algorithm> usingnamespace std; int n, a, b; intgcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } intmain() { scanf("%d", &n); while (n--) { scanf("%d%d", &a, &b); printf("%d\n", gcd(a, b)); } return0; }
#include<iostream> #include<cstdio> #include<vector> #include<algorithm> #include<string> usingnamespace std; int n;
intmain() { scanf("%d",&n); while(n--) { int a = 0; scanf("%d",&a); int res = a; for(int i = 2;i <= a/i; ++i) { if(a % i == 0) { res = res / i * (i - 1); while(a % i == 0) a /= i; } } if(a > 1) res = res / a * (a - 1); cout<<res<<endl; } return0; }
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<algorithm> usingnamespace std; typedeflonglong LL; int n; intqmi(int a, int k, int p) { int res = 1; while (k) { if (k & 1) res = (LL)res * a % p; k >>= 1; a = (LL)a * a % p; } return res; } intmain() { scanf("%d", &n); while (n--) { int a, k, p; scanf("%d%d%d", &a, &k, &p); printf("%d\n", qmi(a, k, p)); } return0; }
LL qmi(int a, int b, int p) { LL res = 1; while (b) { if (b & 1) res = res * a % p; a = (LL)a * a % p; b >>= 1; } return res; }
intmain() { int n; cin >> n; while (n--) { int a, p; cin >> a >> p; if (a % p == 0) puts("impossible"); else cout << qmi(a, p - 2, p) << endl; } return0; }
#include<iostream> #include<cstdio> usingnamespace std; intexgcd(int a, int b, int& x, int& y) { if (!b) { x = 1, y = 0; return a; } else { int d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } }
intmain() { int n; scanf("%d", &n); while (n--) { int a, b, x, y; scanf("%d%d", &a, &b); exgcd(a, b, x, y); printf("%d %d\n", x, y); } return0; }
#include<iostream> #include<cstdio> usingnamespace std; typedeflonglong LL; intexgcd(int a, int b, int& x, int& y) { if (!b) { x = 1, y = 0; return a; } else { int d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } }
intmain() { int n; scanf("%d", &n); while (n--) { int a, b, m; scanf("%d%d%d", &a, &b, &m); int x, y; int d = exgcd(a, m, x, y); if (b % d) puts("impossible"); elseprintf("%d\n", (LL)x * (b / d) % m); } return0; }
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> usingnamespace std; constint N = 110; constdouble eps = 1e-8; int n; double a[N][N];
intgauss()// 高斯消元,答案存于a[i][n]中,0 <= i < n { int c, r; for (c = 0, r = 0; c < n; c++) { int t = r; for (int i = r; i < n; i++) //找绝对值最大的行 if (fabs(a[i][c]) > fabs(a[t][c])) t = i; if (fabs(a[t][c]) < eps) continue; for (int i = c; i <= n; i++) swap(a[t][i], a[r][i]);//将绝对值最大的行换到最顶端 for (int i = n; i >= c; i--) a[r][i] /= a[r][c];//将当前行的首位变成1 for (int i = r + 1; i < n; i++) //用当前行将下面所有的列消成0 if (fabs(a[i][c]) > eps) for (int j = n; j >= c; j--) a[i][j] -= a[r][j] * a[i][c]; r++; } if (r < n) { for (int i = r; i < n; i++) if (fabs(a[i][n]) > eps) return2; //无解 return1; //有无穷多组解 } for (int i = n - 1; i >= 0; i--) for (int j = i + 1; j < n; j++) a[i][n] -= a[i][j] * a[j][n]; return0; //有唯一解 }
intmain() { scanf("%d", &n); for (int i = 0; i < n; i++) for (int j = 0; j < n + 1; j++) scanf("%lf", &a[i][j]); int t = gauss(); if (t == 2) puts("No solution"); elseif (t == 1) puts("Infinite group solutions"); else { for (int i = 0; i < n; i++) { if (fabs(a[i][n]) < eps) a[i][n] = 0; //去掉输出 -0.00 的情况 printf("%.2lf\n", a[i][n]); } } return0; }
#include<iostream> #include<algorithm> usingnamespace std; constint N = 110; int n; int a[N][N]; intgauss() { int c, r; for (c = 0, r = 0; c < n; c++) { // 找主元 int t = -1; for (int i = r; i < n; i++) if (a[i][c]) { t = i; break; } if (t == -1) continue; // 交换主元行 for (int j = c; j <= n; j++) swap(a[r][j], a[t][j]); // 左下角消 for (int i = r + 1; i < n; i++) if (a[i][c])//漏了 for (int j = n; j >= c; j--)//漏了 a[i][j] ^= a[r][j]; r++; } // 判断 if (r < n) { for (int i = r; i < n; i++)//i=r if (a[i][n]) return2; return1; } // 消右上角 for (int i = n - 1; i >= 0; i--) for (int j = i + 1; j < n; j++) //如果是0 就不用下面的a[j][j] 来^a[i][j]了 //如果不是0 才需要用第j行第j列a[j][j]来^第i行第j列a[i][j] //进而进行整行row[i]^row[j] 间接导致 a[i][n]^a[j][n] if (a[i][j]) a[i][n] ^= a[j][n]; return0; }
intmain() { cin >> n; for (int i = 0; i < n; i++) for (int j = 0; j <= n; j++) cin >> a[i][j]; int t = gauss(); if (t == 0) { for (int i = 0; i < n; i++) cout << a[i][n] << endl; } elseif (t == 1) puts("Multiple sets of solutions"); elseputs("No solution"); return0; }
#include<iostream> #include<cstdio> usingnamespace std; typedeflonglong LL; constint N = 100010, mod = 1e9 + 7; int fact[N], infact[N]; intqmi(int a, int k, int p) { int res = 1; while (k) { if (k & 1) res = (LL)res * a % p; a = (LL)a * a % p; k >>= 1; } return res; }
intmain() { fact[0] = infact[0] = 1; for (int i = 1; i < N; i++) { fact[i] = (LL)fact[i - 1] * i % mod; infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod; } int n; scanf("%d", &n); while (n--) { int a, b; scanf("%d%d", &a, &b); printf("%d\n", (LL)fact[a] * infact[b] % mod * infact[a - b] % mod); } return0; }
intqmi(int a, int k, int p) { int res = 1; while (k) { if (k & 1)res = (LL)res * a % p; a = (LL)a * a % p; k >>= 1; } return res; }
intC(int a, int b, int p)//自变量类型int { if (b > a)return0;//漏了边界条件 int res = 1; // a!/(b!(a-b)!) = (a-b+1)*...*a / b! 分子有b项 for (int i = 1, j = a; i <= b; i++, j--)//i<=b而不是< { res = (LL)res * j % p; res = (LL)res * qmi(i, p - 2, p) % p; } return res; } //对公式敲 intlucas(LL a, LL b, int p) { if (a < p && b < p)returnC(a, b, p);//lucas递归终点是C_{bk}^{ak} return (LL)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p; //a%p后肯定是<p的,所以可以用C(),但a/p后不一定<p 所以用lucas继续递归 }
intmain() { int n; cin >> n; while (n--) { LL a, b; int p; cin >> a >> b >> p; cout << lucas(a, b, p) << endl; } return0; }
#include<iostream> #include<algorithm> #include<vector> usingnamespace std; constint N = 5010; int primes[N], cnt; int sum[N]; bool st[N];
voidget_primes(int n) { for (int i = 2; i <= n; i++) { if (!st[i])primes[cnt++] = i; for (int j = 0; primes[j] * i <= n; j++) { st[primes[j] * i] = true; if (i % primes[j] == 0)break;//==0每次漏 } } } // 对p的各个<=a的次数算整除下取整倍数 intget(int n, int p) { int res = 0; while (n) { res += n / p; n /= p; } return res; } //高精度乘 vector<int> mul(vector<int> a, int b) { vector<int> c; int t = 0; for (int i = 0; i < a.size(); i++) { t += a[i] * b; c.push_back(t % 10); t /= 10; } while (t) { c.push_back(t % 10); t /= 10; } // while(C.size()>1 && C.back()==0) C.pop_back();//考虑b==0时才有pop多余的0 b!=0不需要这行 return c; }
intmain() { int a, b; cin >> a >> b; get_primes(a);
for (int i = 0; i < cnt; i++) { int p = primes[i]; sum[i] = get(a, p) - get(a - b, p) - get(b, p);//是a-b不是b-a } vector<int> res; res.push_back(1); for (int i = 0; i < cnt; i++) for (int j = 0; j < sum[i]; j++)//primes[i]的次数 res = mul(res, primes[i]);
for (int i = res.size() - 1; i >= 0; i--) printf("%d", res[i]); puts("");
#include<iostream> #include<cstdio> usingnamespace std; typedeflonglong LL; constint mod = 1e9 + 7; intqmi(int a, int k, int p) { int res = 1; while (k) { if (k & 1) res = (LL)res * a % p; a = (LL)a * a % p; k >>= 1; } return res; } intmain() { int n; cin >> n; int a = 2 * n, b = n; int res = 1; for (int i = a; i > a - b; i--) res = (LL)res * i % mod; for (int i = 1; i <= b; i++) res = (LL)res * qmi(i, mod - 2, mod) % mod; res = (LL)res * qmi(n + 1, mod - 2, mod) % mod; cout << res << endl; return0; }
#include<iostream> usingnamespace std; typedeflonglong LL; constint N = 20; int p[N], n, m; intmain() { cin >> n >> m; for (int i = 0; i < m; i++) cin >> p[i]; int res = 0; //枚举从1 到 1111...(m个1)的每一个集合状态, (至少选中一个集合) for (int i = 1; i < 1 << m; i++) { int t = 1;//选中集合对应质数的乘积 int s = 0;//选中的集合数量 //枚举当前状态的每一位 for (int j = 0; j < m; j++) { //选中一个集合 if (i >> j & 1) { //乘积大于n, 则n/t = 0, 跳出这轮循环 if ((LL)t * p[j] > n) { t = -1; break; } s++; //有一个1,集合数量+1 t *= p[j]; } } if (t == -1) continue; if (s & 1) res += n / t; //选中奇数个集合, 则系数应该是1, n/t为当前这种状态的集合数量 else res -= n / t; //反之则为 -1 } cout << res << endl; return0; }
#include<iostream> usingnamespace std; intmain() { int res = 0; int n; cin >> n; for (int i = 1; i <= n; i++) { int x; cin >> x; if (i % 2) res ^= x; } if (res) puts("Yes"); elseputs("No"); return0; }
#include<iostream> #include<cstring> #include<algorithm> #include<set> usingnamespace std; constint N = 110, M = 10010; int n, m; int f[M], s[N];//s存储的是可供选择的集合,f存储的是所有可能出现过的情况的sg值
intsg(int x) { if (f[x] != -1) return f[x]; //因为取石子数目的集合是已经确定了的,所以每个数的sg值也都是确定的,如果存储过了,直接返回即可 set<int> S; //set代表的是有序集合(注:因为在函数内部定义,所以下一次递归中的S不与本次相同) for (int i = 0; i < m; i++) { int sum = s[i]; if (x >= sum) S.insert(sg(x - sum)); //先延伸到终点的sg值后,再从后往前排查出所有数的sg值 } for (int i = 0;; i++) //循环完之后可以进行选出最小的没有出现的自然数的操作 if (!S.count(i)) return f[x] = i; }
intmain() { cin >> m; for (int i = 0; i < m; i++) cin >> s[i]; cin >> n; memset(f, -1, sizeof(f));//初始化f均为-1,方便在sg函数中查看x是否被记录过 int res = 0; for (int i = 0; i < n; i++) { int x; cin >> x; res ^= sg(x); //观察异或值的变化,基本原理与Nim游戏相同 } if (res) printf("Yes"); elseprintf("No"); return0; }
#include<iostream> #include<cstdio> #include<string> #include<vector> #include<algorithm> usingnamespace std; constint N = 1010; int n, m; int v[N], w[N]; int f[N]; intmain() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >> v[i] >> w[i]; for (int i = 1; i <= n; i++) { for (int j = v[i]; j <= m; j++) { f[j] = max(f[j], f[j - v[i]] + w[i]); } } cout << f[m] << endl; return0; }
#include<iostream> #include<vector> #include<cstdio> #include<algorithm> #include<string> usingnamespace std; constint N = 25000; int n, m; int v[N], w[N]; int f[N]; intmain() { cin >> n >> m; int cnt = 0; for (int i = 1; i <= n; i++) { int a, b, s; cin >> a >> b >> s; int k = 1; while (k <= s) { cnt++; v[cnt] = a * k; w[cnt] = b * k; s -= k; k *= 2; } if (s > 0) { cnt++; v[cnt] = a * s; w[cnt] = b * s; } } n = cnt; for (int i = 1; i <= n; i++) { for (int j = m; j >= v[i]; j--) { f[j] = max(f[j], f[j - v[i]] + w[i]); } } cout << f[m] << endl; return0; }
vector<int> dp(int n) { vector<int> ans(10,0); //记录答案 if(n<=0) return ans; //边界条件 vector<int> nums; while(n) nums.push_back(n%10), n/=10; vector<int> last(10,0); //记录前缀中各个数字个数 //统计1 - 99……9(n-1个9)里面各个数字有多少个 for(int i = 0 ; i <= 9 ; i++) ans[i] = g[nums.size()-1][i]; //统计大于10……0(n-1个0) 的树里各个数字有多少个 for(int i = nums.size()-1 ; i >=0 ; i--) { //循环变量i可以表示剩下的数字有多少个 int x = nums[i]; for(int j = i==nums.size()-1 ; j < x ; j++) //第一次循环不能有0 { //前缀部分 for(int k = 0 ; k <= 9 ; k++) ans[k] += last[k] * base[i]; //当前位置部分 ans[j] += base[i]; //后缀部分 for(int k = 0 ; k <= 9 ; k++) ans[k] += f[i][k]; } //更新前缀计数器 last[x] ++;
//统计叶子节点(这个数本身) if(!i) for(int k = 0 ; k <= 9 ; k++) ans[k] += last[k]; } return ans; }
vector<int> ask(int a, int b) { auto x = dp(b); auto y = dp(a-1); vector<int> ans; for(int i = 0 ; i <= 9 ; i++) ans.push_back(x[i]-y[i]); return ans; }
intmain() { int n; scanf("%d", &n); priority_queue<int, vector<int>, greater<int>> heap; while (n -- ) { int x; scanf("%d", &x); heap.push(x); } int res = 0; while (heap.size() > 1) { int a = heap.top(); heap.pop(); int b = heap.top(); heap.pop(); res += a + b; heap.push(a + b); } printf("%d\n", res); return0; }