From 4a5b6647126167369fd816ccc310ec8072e7959a Mon Sep 17 00:00:00 2001 From: Departuers <2644631299@qq.com> Date: Tue, 1 Sep 2020 08:03:10 +0800 Subject: [PATCH] c --- ...\345\205\253\346\225\260\347\240\201.java" | 2 +- ...347\254\254k\347\237\255\350\267\257.java" | 4 +- ...\346\200\247\345\211\252\346\236\235.java" | 10 +- "ACWing/src/LCA/Tarjan\346\261\202LCA.java" | 31 +++-- .../src/LCA/\345\200\215\345\242\236LCA.java" | 2 +- ...\347\224\237\346\210\220\346\240\221.java" | 1 + ...213\211\345\272\217ST\346\261\202LCA.java" | 6 +- ...\345\255\231\350\257\242\351\227\256.java" | 8 +- .../LCA/\350\267\235\347\246\273Tarjan.java" | 28 ++--- .../LIS\351\242\230\350\247\243.java" | 6 +- ...\345\245\266\350\277\220\350\276\223.java" | 80 ++++++++++-- ...\346\263\274\346\260\264\350\212\202.java" | 2 +- ...\345\277\253\351\200\237\344\271\230.java" | 3 +- .../\350\266\212\347\213\261.java" | 8 +- ...\345\205\260\345\233\276\350\205\276.java" | 1 - .../seg.java" | 118 ++++++++++++++++++ ...345\217\226n\346\273\241\350\266\263.java" | 3 +- ...\345\210\227\346\236\232\344\270\276.java" | 13 +- ...\345\220\233\345\256\266\350\260\261.java" | 3 +- ...\346\234\272\351\200\211\346\225\260.java" | 40 +++++- 20 files changed, 293 insertions(+), 76 deletions(-) create mode 100644 "ACWing/src/\347\272\277\346\256\265\346\240\221/seg.java" diff --git "a/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\345\205\253\346\225\260\347\240\201.java" "b/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\345\205\253\346\225\260\347\240\201.java" index 4935e03..187d3ba 100644 --- "a/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\345\205\253\346\225\260\347\240\201.java" +++ "b/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\345\205\253\346\225\260\347\240\201.java" @@ -59,7 +59,7 @@ public class 八数码 { // System.out.println(bfs()); } } - +// // static int bfs(String start) { // HashMap dist = new HashMap(); // HashMap prev = new HashMap(); diff --git "a/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\347\254\254k\347\237\255\350\267\257.java" "b/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\347\254\254k\347\237\255\350\267\257.java" index 7e0d6d1..e24f76c 100644 --- "a/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\347\254\254k\347\237\255\350\267\257.java" +++ "b/ACWing/src/DFS/\345\220\257\345\217\221\345\274\217\346\220\234\347\264\242/\347\254\254k\347\237\255\350\267\257.java" @@ -119,7 +119,7 @@ public class 第k短路 { he[a] = idx++; } - //处理估价函数 + //处理估价函数,从终点往前搜 static void dijkstra() { PriorityQueue q = new PriorityQueue(); q.add(new node(0, T)); @@ -147,7 +147,7 @@ public class 第k短路 { while (!q.isEmpty()) { tem p = q.poll(); int v = p.t.to, dis = p.t.dis; - if (v == T) { + if (v == T) {//记录出队次数 cnt++; } if (cnt == K) return dis;//第k短路 diff --git "a/ACWing/src/DFS/\351\207\215\345\244\215\346\200\247\345\211\252\346\236\235.java" "b/ACWing/src/DFS/\351\207\215\345\244\215\346\200\247\345\211\252\346\236\235.java" index c73c3e0..c805d1a 100644 --- "a/ACWing/src/DFS/\351\207\215\345\244\215\346\200\247\345\211\252\346\236\235.java" +++ "b/ACWing/src/DFS/\351\207\215\345\244\215\346\200\247\345\211\252\346\236\235.java" @@ -23,17 +23,17 @@ public class 重复性剪枝 { static boolean[] vis = new boolean[30]; //当前位置,当前和 w选了多少个 - static void dfs(int cnt, int s, int w) { - if (k - w > n - cnt + 1) return; + static void dfs(int u, int s, int w) { + if (k - w > n - u + 1) return; if (s > sum || w > k) return; - if (cnt == n) { + if (u == n) { if (s == sum && w == k) { ans++; } return; } - dfs(cnt + 1, s + a[cnt], w + 1); - dfs(cnt + 1, s, w); + dfs(u + 1, s + a[u], w + 1); + dfs(u + 1, s, w); } static void ddf(int s, int cnt, int pos) { diff --git "a/ACWing/src/LCA/Tarjan\346\261\202LCA.java" "b/ACWing/src/LCA/Tarjan\346\261\202LCA.java" index 85a52db..0a45aba 100644 --- "a/ACWing/src/LCA/Tarjan\346\261\202LCA.java" +++ "b/ACWing/src/LCA/Tarjan\346\261\202LCA.java" @@ -10,14 +10,22 @@ import static java.lang.System.in; * 离线 * 预处理O(n) * 单次查询O(1) + * 5 5 4 + * 3 1 + * 2 4 + * 5 1 + * 1 4 + * 2 4 + * 3 2 + * 3 5 + * 1 2 + * 4 5 + * out + * 4 + * 4 * 1 - * 1 - * 2 - * 2 - * 1 * 4 - * 7 - * 3 + * 4 * 洛谷3379 ac了居然1.23秒也算ac * 最好的版本!!! */ @@ -46,7 +54,7 @@ public class Tarjan求LCA { } public static void main(String[] args) throws IOException { - for (int i = 0; i < parent.length; i++) { + for (int i = 1; i < parent.length; i++) { parent[i] = i; } n = nextInt(); @@ -102,10 +110,11 @@ public class Tarjan求LCA { static void tarjan(int u, int fa) { for (int i = he[u]; i != 0; i = ne[i]) { - if (e[i] != fa) { - tarjan(e[i], u); - union(e[i], u); - vis[e[i]] = true; + int j = e[i]; + if (j != fa) { + tarjan(j, u); + union(j, u); + vis[j] = true; } } for (int i = qheadedge[u]; i != 0; i = qnext[i]) { diff --git "a/ACWing/src/LCA/\345\200\215\345\242\236LCA.java" "b/ACWing/src/LCA/\345\200\215\345\242\236LCA.java" index 0e9e840..35b49fd 100644 --- "a/ACWing/src/LCA/\345\200\215\345\242\236LCA.java" +++ "b/ACWing/src/LCA/\345\200\215\345\242\236LCA.java" @@ -73,7 +73,7 @@ public class 倍增LCA { /** * 求取每个节点深度 * 和dist[a]存的是a往上直到根节点的权值和 - * + * 也可以用bfs * @param u 当前节点 * @param fa 父节点 * @param d 该节点的深度 diff --git "a/ACWing/src/LCA/\346\254\241\345\260\217\347\224\237\346\210\220\346\240\221.java" "b/ACWing/src/LCA/\346\254\241\345\260\217\347\224\237\346\210\220\346\240\221.java" index 72a24ca..d846877 100644 --- "a/ACWing/src/LCA/\346\254\241\345\260\217\347\224\237\346\210\220\346\240\221.java" +++ "b/ACWing/src/LCA/\346\254\241\345\260\217\347\224\237\346\210\220\346\240\221.java" @@ -8,6 +8,7 @@ import java.util.StringTokenizer; import static java.lang.System.in; /** + * * https://blog.csdn.net/qq_41661919/article/details/86565228 * https://blog.csdn.net/qq_44828887/article/details/107305636 * 给定一张 N 个点 M 条边的无向图,求无向图的严格次小生成树。 * 设最小生成树的边权之和为sum, diff --git "a/ACWing/src/LCA/\346\254\247\346\213\211\345\272\217ST\346\261\202LCA.java" "b/ACWing/src/LCA/\346\254\247\346\213\211\345\272\217ST\346\261\202LCA.java" index 476aec0..93a6000 100644 --- "a/ACWing/src/LCA/\346\254\247\346\213\211\345\272\217ST\346\261\202LCA.java" +++ "b/ACWing/src/LCA/\346\254\247\346\213\211\345\272\217ST\346\261\202LCA.java" @@ -19,7 +19,7 @@ import static java.lang.System.in; * 注意欧拉序要开2倍! * 预处理O(n log n) 在线 * 查询O(1) - * 洛谷3379 re4个..tle3个.. + * 洛谷3379 tle3个..超时 */ public class 欧拉序ST求LCA { public static void main(String[] args) throws IOException { @@ -59,9 +59,9 @@ public class 欧拉序ST求LCA { return Double.parseDouble(next()); } - static int[] log = new int[25]; static int n, m, len = 0, cnt = 1, root; static final int maxn = 500005; + static int[] log = new int[maxn]; static int[][] st = new int[maxn << 1][20]; static int[] depth = new int[maxn << 1];//深度 static int[] euler = new int[maxn << 1];//欧拉序 @@ -82,7 +82,7 @@ public class 欧拉序ST求LCA { static void init(int root) { dfs(root, root, 1); log[1] = 0; - for (int i = 2; i < 25; i++) { + for (int i = 2; i < maxn; i++) { log[i] = log[i / 2] + 1; } for (int i = 1; i <= len; i++) { diff --git "a/ACWing/src/LCA/\347\245\226\345\255\231\350\257\242\351\227\256.java" "b/ACWing/src/LCA/\347\245\226\345\255\231\350\257\242\351\227\256.java" index d885c43..d3782f6 100644 --- "a/ACWing/src/LCA/\347\245\226\345\255\231\350\257\242\351\227\256.java" +++ "b/ACWing/src/LCA/\347\245\226\345\255\231\350\257\242\351\227\256.java" @@ -73,7 +73,7 @@ public class 祖孙询问 { if (depth[up[a][k]] >= depth[b]) { a = up[a][k]; } - } + }//从高往低跳 if (a == b) return a; for (int k = 17; k >= 0; k--) { if (up[a][k] != up[b][k]) { @@ -112,10 +112,10 @@ public class 祖孙询问 { for (int i = h[t]; i != 0; i = ne[i]) { int j = e[i]; if (depth[j] > depth[t] + 1) { - depth[j] = depth[t] + 1; + depth[j] = depth[t] + 1;//bfs拓展 q.add(j); - up[j][0] = t; - for (int k = 1; k <= 17; k++) { + up[j][0] = t;//记录第一个 + for (int k = 1; k <= 17; k++) {//记录后面的up up[j][k] = up[up[j][k - 1]][k - 1]; } } diff --git "a/ACWing/src/LCA/\350\267\235\347\246\273Tarjan.java" "b/ACWing/src/LCA/\350\267\235\347\246\273Tarjan.java" index 784fc66..fd4fab0 100644 --- "a/ACWing/src/LCA/\350\267\235\347\246\273Tarjan.java" +++ "b/ACWing/src/LCA/\350\267\235\347\246\273Tarjan.java" @@ -44,6 +44,12 @@ import java.util.Scanner; */ public class 距离Tarjan { public static void main(String[] args) { + for (int i = 1; i < p.length; i++) { + p[i] = i; + } + for (int i = 0; i < query.length; i++) { + query[i] = new ArrayList(); + } Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); @@ -67,7 +73,7 @@ public class 距离Tarjan { dfs(1, -1); tarjan(1); for (int i = 0; i < m; i++) { - System.out.println(res[i]); + System.out.println(result[i]); } } @@ -78,11 +84,11 @@ public class 距离Tarjan { static int[] w = new int[M]; static int[] ne = new int[N]; static int[] st = new int[N]; - static int[] res = new int[N]; + static int[] result = new int[N];//预处理查询 static int[] p = new int[N]; static int[] dist = new int[N];//记录每个点到根节点的距离 - //求每个点到根节点的距离 + //求每个点到根节点的距离,前序遍历 static void dfs(int u, int fa) { for (int i = h[u]; i != 0; i = ne[i]) { int j = e[i]; @@ -101,11 +107,12 @@ public class 距离Tarjan { p[j] = u; } } - for (node it : query[u]) { + for (node it : query[u]) {//u->y这条查询,查询编号为2 int y = it.a, id = it.b; if (st[y] == 2) { - int anc = find(y); - res[id] = dist[u] + dist[y] - dist[anc] * 2; + int anc = find(y);//最近公共祖先 + result[id] = dist[u] + dist[y] - dist[anc] * 2; + //u到根节点的距离加上y到根节点的距离减去两个最近共祖先到根节点的距离,就是两点之间的距离 } } st[u] = 2; @@ -133,13 +140,4 @@ public class 距离Tarjan { } static ArrayList[] query = new ArrayList[N]; - - static { - for (int i = 1; i < p.length; i++) { - p[i] = i; - } - for (int i = 0; i < query.length; i++) { - query[i] = new ArrayList(); - } - } } diff --git "a/ACWing/src/dp/\347\272\277\346\200\247dp/LIS\346\250\241\345\236\213/LIS\351\242\230\350\247\243.java" "b/ACWing/src/dp/\347\272\277\346\200\247dp/LIS\346\250\241\345\236\213/LIS\351\242\230\350\247\243.java" index e4cbb14..f61974a 100644 --- "a/ACWing/src/dp/\347\272\277\346\200\247dp/LIS\346\250\241\345\236\213/LIS\351\242\230\350\247\243.java" +++ "b/ACWing/src/dp/\347\272\277\346\200\247dp/LIS\346\250\241\345\236\213/LIS\351\242\230\350\247\243.java" @@ -17,14 +17,14 @@ public class LIS题解 { static int n; static int[] arr = new int[100005]; - static int[] dp = new int[100005]; static int lis() { + int[] f = new int[100005]; int i = 0, len = 0; for (int j = 0; j < n; j++) { - i = Arrays.binarySearch(dp, 0, len, arr[j]); + i = Arrays.binarySearch(f, 0, len, arr[j]); if (i < 0) i = -(i + 1); - dp[i] = arr[j]; + f[i] = arr[j]; if (i == len) len++; } return len; diff --git "a/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\347\211\233\345\245\266\350\277\220\350\276\223.java" "b/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\347\211\233\345\245\266\350\277\220\350\276\223.java" index 5f6ddbc..3a56717 100644 --- "a/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\347\211\233\345\245\266\350\277\220\350\276\223.java" +++ "b/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\347\211\233\345\245\266\350\277\220\350\276\223.java" @@ -5,19 +5,35 @@ import java.util.Collections; import java.util.Scanner; /** - * https://blog.csdn.net/qq_41661919/article/details/86565228 - * https://blog.csdn.net/qq_44828887/article/details/107305636 - * 给定一张 N 个点 M 条边的无向图,求无向图的严格次小生成树。 - * 设最小生成树的边权之和为sum,严格次小生成树就是指边权之和大于sum的生成树中最小的一个。 + * https://blog.csdn.net/qq_30277239/article/details/108190012 + * 农夫约翰要把他的牛奶运输到各个销售点。 + * 运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点。 + * 运输的总距离越小,运输的成本也就越低。 + * 低成本的运输是农夫约翰所希望的。 + * 不过,他并不想让他的竞争对手知道他具体的运输方案,所以他希望采用费用第二小的运输方案而不是最小的。 + * 现在请你帮忙找到该运输方案。 + * 如果两个方案至少有一条边不同,则我们认为是不同方案; + * 费用第二小的方案在数值上一定要严格小于费用最小的方案; + * 答案保证一定有解; * 输入格式 - * 第一行包含两个整数N和M。 - * 接下来M行,每行包含三个整数x,y,z,表示点x和点y之前存在一条边,边的权值为z。 + * 第一行是两个整数 N,M,表示销售点数和交通线路数; + * 接下来 M 行每行 3 个整数 x,y,z,表示销售点 x 和销售点 y 之间存在线路,长度为 z。 * 输出格式 - * 包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树) + * 输出费用第二小的运输方案的运输总距离。 * 数据范围 - * N≤105,M≤3∗105 - * 思路 - * lca次小生成树。倍增找树上路径最大边即可。 + * 1≤N≤500, + * 1≤M≤10^4, + * 1≤z≤10^9, + * 数据中可能包含重边。 + * 输入样例: + * 输入样例: + * 4 4 + * 1 2 100 + * 2 4 200 + * 2 3 250 + * 3 4 100 + * 输出样例: + * 450 */ public class 牛奶运输 { public static void main(String[] args) { @@ -53,7 +69,7 @@ public class 牛奶运输 { } long res = (long) 1e18; for (int i = 0; i < m; i++) { - if (!edge.get(i).isShu) { + if (!edge.get(i).isShu) {//遍历非树边 a = edge.get(i).a; b = edge.get(i).b; w = edge.get(i).w; @@ -65,6 +81,14 @@ public class 牛奶运输 { System.out.println(res); } + /** + * 枚举任意两点路径的最大边权的那条边,由dis[a,b]表示a,b两点路径的最大边权的那条边 + * + * @param u 当前点 + * @param fa 父节点 + * @param maxd 最大边权 + * @param d 结果记录 + */ static void dfs(int u, int fa, int maxd, int[] d) { d[u] = maxd; for (int i = h[u]; i != 0; i = ne[i]) { @@ -75,6 +99,36 @@ public class 牛奶运输 { } } + /** + * 求任意两点路径中的单条边权最大值,和次大值 + * + * @param u 当前节点 + * @param fa 父节点,从哪来的 + * @param r1 最大值 + * @param r2 次大值 + * @param s1 记录最大值 + * @param s2 记录次大值 + */ + static void dubbo(int u, int fa, int r1, int r2, int[] s1, int[] s2) { + s1[u] = r1; + s2[u] = r2; + for (int i = h[u]; i != 0; i = ne[i]) { + int j = e[i]; + if (j != fa) { + int t1 = r1, t2 = r2;//结合当前边的边权修改最大值,最小值 + if (w[i] > t1) {//当前边权比最大值还大 + t2 = t1; + t1 = w[i]; + } else if (w[i] > t2 && w[i] != t1) { + //当前边权小于最大值,大于次大值,但不可以与最大值相等,求的是严格次大值 + t2 = w[i]; + } + dubbo(j, u, t1, t2, s1, s2); + } + } + } + + static void add(int a, int b, int c) { e[cnt] = b; w[cnt] = c; @@ -106,9 +160,11 @@ public class 牛奶运输 { static int n, m, N = 510, cnt = 1, M = 10010; static ArrayList edge = new ArrayList(); static int[] p = new int[N];//并查集 - static int[][] dis = new int[N][N]; + static int[][] dis = new int[N][N];//两点路径中单条边权最大值,参见dfs static int[] h = new int[N]; static int[] e = new int[M]; static int[] w = new int[M]; static int[] ne = new int[M]; + static int[][] m1 = new int[N][N];//两点路径中单条边权最大值,用dubbo方法求解 + static int[][] m2 = new int[N][N];//两点路径中单条边权次大值 } diff --git "a/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\350\265\260\345\273\212\346\263\274\346\260\264\350\212\202.java" "b/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\350\265\260\345\273\212\346\263\274\346\260\264\350\212\202.java" index abad0ed..fa5553b 100644 --- "a/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\350\265\260\345\273\212\346\263\274\346\260\264\350\212\202.java" +++ "b/ACWing/src/graph/\346\234\200\345\260\217\347\224\237\346\210\220\346\240\221\346\213\223\345\261\225/\350\265\260\345\273\212\346\263\274\346\260\264\350\212\202.java" @@ -38,7 +38,7 @@ public class 走廊泼水节 { res += (size[a] * size[b] - 1) * (c.w + 1);//新边都取w+1 System.out.println(Arrays.toString(size)); size[b] += size[a];//合并两个集合 - par[a] = b; + par[a] = b;//a指向b } } System.out.println(res); diff --git "a/ACWing/src/\346\225\260\345\255\246/\345\277\253\351\200\237\344\271\230.java" "b/ACWing/src/\346\225\260\345\255\246/\345\277\253\351\200\237\344\271\230.java" index 2a199a8..ff64254 100644 --- "a/ACWing/src/\346\225\260\345\255\246/\345\277\253\351\200\237\344\271\230.java" +++ "b/ACWing/src/\346\225\260\345\255\246/\345\277\253\351\200\237\344\271\230.java" @@ -34,7 +34,8 @@ public class 快速乘 { System.out.println(ks(a, b, p)); System.out.println(ca(2, 20)); } - //递归快速乘 + + //递归快速乘转化为加法 static int ca(int a, int b) { int res = 0; if (b == 0) return res; diff --git "a/ACWing/src/\346\225\260\345\255\246/\350\266\212\347\213\261.java" "b/ACWing/src/\346\225\260\345\255\246/\350\266\212\347\213\261.java" index 723cc19..d5857e7 100644 --- "a/ACWing/src/\346\225\260\345\255\246/\350\266\212\347\213\261.java" +++ "b/ACWing/src/\346\225\260\345\255\246/\350\266\212\347\213\261.java" @@ -5,12 +5,12 @@ import java.util.Scanner; /** * https://www.acwing.com/solution/acwing/content/12579/ * https://www.hzxueyan.com/archives/85/ - * 监狱有连续编号为 11 到 nn 的 nn 个房间,每个房间关押一个犯人。 - * 有 mm 种宗教,每个犯人可能信仰其中一种。 + * 监狱有连续编号为 1 到 n 的 n 个房间,每个房间关押一个犯人。 + * 有 m种宗教,每个犯人可能信仰其中一种。 * 如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。 * 求有多少种状态可能发生越狱。 * 输入 - * 共一行,包含两个整数 mm 和 nn。 + * 共一行,包含两个整数 m 和 n。 * 输出 * 可能越狱的状态数,对 100003取余。 * 数据范围 @@ -19,7 +19,7 @@ import java.util.Scanner; * 输出样例 * 6 * 样例解释 - * 所有可能的 66 种状态为:(000)(001)(011)(100)(110)(111)(000)(001)(011)(100)(110)(111)。 + * 所有可能的 6 种状态为:(000)(001)(011)(100)(110)(111) */ public class 越狱 { public static void main(String[] args) { diff --git "a/ACWing/src/\346\240\221\347\212\266\346\225\260\347\273\204/\346\245\274\345\205\260\345\233\276\350\205\276.java" "b/ACWing/src/\346\240\221\347\212\266\346\225\260\347\273\204/\346\245\274\345\205\260\345\233\276\350\205\276.java" index 484814e..3cd00af 100644 --- "a/ACWing/src/\346\240\221\347\212\266\346\225\260\347\273\204/\346\245\274\345\205\260\345\233\276\350\205\276.java" +++ "b/ACWing/src/\346\240\221\347\212\266\346\225\260\347\273\204/\346\245\274\345\205\260\345\233\276\350\205\276.java" @@ -17,7 +17,6 @@ public class 楼兰图腾 { n = sc.nextInt(); for (int i = 1; i <= n; i++) { a[i] = sc.nextInt(); -// max_value = Math.max(a[i], max_value);//记录数组最大值 } /** * 正序循环,巧妙想法,也可以求逆序数 diff --git "a/ACWing/src/\347\272\277\346\256\265\346\240\221/seg.java" "b/ACWing/src/\347\272\277\346\256\265\346\240\221/seg.java" new file mode 100644 index 0000000..588323b --- /dev/null +++ "b/ACWing/src/\347\272\277\346\256\265\346\240\221/seg.java" @@ -0,0 +1,118 @@ +package 线段树; + +import java.io.*; +import java.util.StringTokenizer; + +import static java.lang.System.in; + +public class seg { + public static void main(String[] args) throws IOException { + n = nextInt(); + m = nextInt(); + build(1, 1, n); + int l, r, d; + while (m-- != 0) { + if (next().charAt(0) == 'C') { + l = nextInt(); + r = nextInt(); + d = nextInt(); + update(1, l, r, d); + } else { + l = nextInt(); + r = nextInt(); + bw.write(query(1, l, r) + "\n"); + } + } + bw.flush(); + } + + static class node { + int l, r; + long sum;//区间和 + int lazy;//懒标记,给当前节点为根的子树中的每一个节点加上lazy(设计不包含根节点) + //只要递归到子区间就pushdown + + public node(int l, int r, int sum) { + this.l = l; + this.r = r; + this.sum = sum; + } + } + + static void build(int k, int l, int r) throws IOException { + if (l == r) { + tr[k] = new node(l, r, nextInt()); + } else { + tr[k] = new node(l, r, 0); + int mid = l + r >> 1; + build(k << 1, l, mid); + build(k << 1 | 1, mid + 1, r); + pushup(k); + } + } + + private static void pushup(int k) { + tr[k].sum = tr[k << 1].sum + tr[k << 1 | 1].sum; + } + + static void update(int k, int l, int r, int d) { + if (tr[k].l >= l && tr[k].r <= r) { + tr[k].sum += (tr[k].r - tr[k].l + 1) * d; + tr[k].lazy += d; + return; + } + down(k); + int mid = tr[k].l + tr[k].r >> 1; + if (l <= mid) update(k << 1, l, r, d); + if (r > mid) update(k << 1 | 1, l, r, d); + pushup(k); + } + + static long query(int k, int l, int r) { + if (tr[k].l >= l && tr[k].r <= r) { + return tr[k].sum; + } + down(k); + int mid = tr[k].l + tr[k].r >> 1; + long ans = 0; + if (l <= mid) ans += query(k << 1, l, r); + if (r > mid) ans += query(k << 1 | 1, l, r); + return ans; + } + + private static void down(int k) { + if (tr[k].lazy != 0) { + tr[k << 1].sum += (tr[k << 1].r - tr[k << 1].l + 1) * tr[k].lazy; + tr[k << 1 | 1].sum += (tr[k << 1 | 1].r - tr[k << 1 | 1].l + 1) * tr[k].lazy; + tr[k << 1].lazy += tr[k].lazy; + tr[k << 1 | 1].lazy += tr[k].lazy; + tr[k].lazy = 0; + } + } + + static int N = (int) (1e5 + 2), n, m; + static node[] tr = new node[N * 4]; + static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); + static BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + static StringTokenizer tokenizer = new StringTokenizer(""); + + static String nextLine() throws IOException {// 读取下一行字符串 + return reader.readLine(); + } + + static String next() throws IOException {// 读取下一个字符串 + while (!tokenizer.hasMoreTokens()) { + //如果没有字符了,就是下一个,使用空格拆分, + tokenizer = new StringTokenizer(reader.readLine()); + } + return tokenizer.nextToken(); + } + + static int nextInt() throws IOException {// 读取下一个int型数值 + return Integer.parseInt(next()); + } + + static double nextDouble() throws IOException {// 读取下一个double型数值 + return Double.parseDouble(next()); + } +} diff --git "a/ACWing/src/\351\200\222\345\275\222/m\344\273\273\345\217\226n\346\273\241\350\266\263.java" "b/ACWing/src/\351\200\222\345\275\222/m\344\273\273\345\217\226n\346\273\241\350\266\263.java" index 2296236..350bb44 100644 --- "a/ACWing/src/\351\200\222\345\275\222/m\344\273\273\345\217\226n\346\273\241\350\266\263.java" +++ "b/ACWing/src/\351\200\222\345\275\222/m\344\273\273\345\217\226n\346\273\241\350\266\263.java" @@ -40,7 +40,7 @@ public class m任取n满足 { static void f(int u, int sum, int s) { if (sum + n - u < k) return;//n-u是剩余可选的数, if (sum > k) return; - if (u == n) { + if (u == n) {//枚举到最后一个元素 if (sum == k && s == suma) ans++; return; @@ -50,6 +50,7 @@ public class m任取n满足 { f(u + 1, sum + 1, s + arr[u]); } + static boolean[] x = new boolean[30]; /** diff --git "a/ACWing/src/\351\200\222\345\275\222/\346\216\222\345\210\227\346\236\232\344\270\276.java" "b/ACWing/src/\351\200\222\345\275\222/\346\216\222\345\210\227\346\236\232\344\270\276.java" index 2e61a37..52066de 100644 --- "a/ACWing/src/\351\200\222\345\275\222/\346\216\222\345\210\227\346\236\232\344\270\276.java" +++ "b/ACWing/src/\351\200\222\345\275\222/\346\216\222\345\210\227\346\236\232\344\270\276.java" @@ -1,6 +1,7 @@ package 递归; import java.util.ArrayList; +import java.util.Arrays; import java.util.Scanner; import static java.lang.System.in; @@ -35,7 +36,7 @@ public class 排列枚举 { Scanner sc = new Scanner(in); n = sc.nextInt(); long s = System.nanoTime(); - d(0, 0); + d( 0); long t = System.nanoTime(); System.out.println((t - s) / 1e8); s = System.nanoTime(); @@ -66,17 +67,17 @@ public class 排列枚举 { } } - static int[] arr = {4, 3, 5, 2, 3, 4, 1, 4, 5, 1, 2}; + static int[] arr = {1, 2, 3, 4, 5, 4, 1, 4, 5, 1, 2}; //最快 - static void d(int u, int k) { - if (u == n) { -// System.out.println(Arrays.toString(arr)); + static void d( int k) { + if (k== n) { + System.out.println(Arrays.toString(arr)); return; } for (int i = k; i < n; i++) { swap(i, k); - d(u + 1, k + 1); + d( k + 1); swap(i, k); } } diff --git "a/ACWing/src/\351\200\222\345\275\222/\350\222\234\345\244\264\345\220\233\345\256\266\350\260\261.java" "b/ACWing/src/\351\200\222\345\275\222/\350\222\234\345\244\264\345\220\233\345\256\266\350\260\261.java" index 138cbde..177bf49 100644 --- "a/ACWing/src/\351\200\222\345\275\222/\350\222\234\345\244\264\345\220\233\345\256\266\350\260\261.java" +++ "b/ACWing/src/\351\200\222\345\275\222/\350\222\234\345\244\264\345\220\233\345\256\266\350\260\261.java" @@ -4,7 +4,8 @@ import java.util.Scanner; /** * https://blog.csdn.net/qq_38735931/article/details/89395313#A%20%E5%AE%B6%E8%B0%B1%C2%A0 - * 这一天蒜头君拿到了自己家的家谱,蒜头君便想知道,在自己家的家谱中,每位祖先有多少直系后代(直系后代包括他的孩子和他孩子的直系后代)。但是家族历史源远流长,家谱实在太庞大了,自己一个人完全数不过来。热心的你便自告奋勇帮蒜头君写一个程序,来统计每位祖先有多少直系后代。 + * 这一天蒜头君拿到了自己家的家谱,蒜头君便想知道,在自己家的家谱中,每位祖先有多少直系后代(直系后代包括他的孩子和他孩子的直系后代)。 + * 但是家族历史源远流长,家谱实在太庞大了,自己一个人完全数不过来。热心的你便自告奋勇帮蒜头君写一个程序,来统计每位祖先有多少直系后代。 * 输入格式 * 输入的第一行有一个整数 n(1≤n≤100000),表示家谱中的总人数。 * 接下来读入 n−1行,每行有两个整数 x(1≤x≤n), y(1≤y≤n),表示 x 是 y 的父母。 diff --git "a/ACWing/src/\351\200\222\345\275\222/\351\232\217\346\234\272\351\200\211\346\225\260.java" "b/ACWing/src/\351\200\222\345\275\222/\351\232\217\346\234\272\351\200\211\346\225\260.java" index 8dd9de9..6c76d87 100644 --- "a/ACWing/src/\351\200\222\345\275\222/\351\232\217\346\234\272\351\200\211\346\225\260.java" +++ "b/ACWing/src/\351\200\222\345\275\222/\351\232\217\346\234\272\351\200\211\346\225\260.java" @@ -25,14 +25,30 @@ package 递归; */ public class 随机选数 { public static void main(String[] args) { + // Scanner sc = new Scanner(in); // n = sc.nextInt(); - dfs(0, 0); +// long l = System.nanoTime(); +// f(0); +// long r = System.nanoTime(); +// System.out.println((r - l) / 1e8); +// l = System.nanoTime(); + //dfs(0, 0); + for (int i = 0; i < 1 << n; i++) { + for (int j = 0; j < n; j++) { + if ((i >> j & 1) == 1) + System.out.print(j + 1 + " "); + } + System.out.println(); + } + //位运算求子集 +// r = System.nanoTime(); +// System.out.println((r - l) / 1e8); } - static int n = 3; - static int[] arr = {1, 2, 3}; + static int n = 4; + static int[] arr = {1, 2, 3, 4, 5, 6}; static int[] vis = new int[10]; //dfs求子集,选和不选 @@ -54,9 +70,25 @@ public class 随机选数 { vis[u] = 0; } + static boolean[] st = new boolean[23]; + + static void f(int u) { + if (u == n) { + for (int i = 0; i < n; i++) { + if (st[i]) System.out.print(arr[i] + " "); + } + System.out.println(); + return; + } + f(u + 1); + st[u] = true; + f(u + 1); + st[u] = false; + } + static void dfs(int u, int state) { if (u == n) { - if (state==0)return; + if (state == 0) return; for (int i = 0; i < n; i++) { if (((state >> i) & 1) == 1) System.out.print(arr[i] + " "); -- GitLab