提交 916df8b0 编写于 作者: qq_36480062's avatar qq_36480062

c

上级 0c34f05d
......@@ -70,7 +70,7 @@ public class 运输小猫 {
sum[i] -= w[u];
}
}
//k的取值是0~k-1,所以k就是下一辆车
//k的取值是0~k-1,所以下一次递归k就是下一辆车
sum[k] = w[u];
dfs(u + 1, k + 1);
sum[k] = 0;
......@@ -82,7 +82,7 @@ public class 运输小猫 {
* @param u
*/
static void f(int u) {
if (len >= ans) return;
if (len >= ans) return;//最优性剪枝
if (u == n) {
ans = len;
System.out.println(Arrays.toString(car));//每辆车放多少个
......
......@@ -34,7 +34,7 @@ import static java.lang.System.in;
* 找每个点到指定最近的终点
* 显然:多源最短路,求每个点到一堆起点的距离,终点不唯一找出最近,可以转化成单源最短路
* 有一个虚拟头结点,与所有起点有一条边权为0的边,
* 体现在bfs中就是队列中添加所有起点!!!
* 体现在bfs中就是队列中添加所有起点!!!也就是把要到的位置加入对队列作为起点
* 体现在dijkstra就是要真的把那个源点建立出来
*/
public class 矩阵距离 {
......
......@@ -31,8 +31,8 @@ public class IO加速 {
public static void main(String[] args) throws IOException {
// fff();
// sw();
dfs(4, 1, new ArrayList<Integer>());
// f();
///dfs(4, 1, new ArrayList<Integer>());
f();
// tokenizer = new StringTokenizer("123123 15412 4312412");
// System.out.println(tokenizer.nextToken());
// System.out.println(tokenizer.nextToken());
......@@ -82,53 +82,6 @@ public class IO加速 {
}
}
static void sw() {
long s = System.nanoTime();
for (int i = 0; i < par.length; i++) {
par[i] = i;
}
for (int i = 0; i < par.length; i++) {
union(1, i);
}
long t = System.nanoTime();
System.out.println((t - s) / 1e8);
s = System.nanoTime();
for (int i = 0; i < par.length; i++) {
par[i] = i;
}
for (int i = 0; i < par.length; i++) {
unio(i, 0);
}
t = System.nanoTime();
System.out.println((t - s) / 1e8);
}
static void union(int x, int y) {
x = find(x);
y = find(y);
if (x != y) par[x] = y;
}
static void unio(int x, int y) {
x = fin(x);
y = fin(y);
if (x != y) par[x] = y;
}
static int find(int x) {
while (x != par[x]) {
par[x] = par[par[x]];
x = par[x];
}
return x;
}
static int fin(int x) {
if (x == par[x]) return x;
return par[x] = fin(par[x]);
}
static int[] par = new int[11000000];
......
......@@ -8,7 +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_41661919/article/details/86565228
* https://blog.csdn.net/qq_44828887/article/details/107305636
* 给定一张 N 个点 M 条边的无向图,求无向图的严格次小生成树。
* 设最小生成树的边权之和为sum,
......
......@@ -63,18 +63,20 @@ public class 祖孙询问 {
else if (p == b) System.out.println(2);
else System.out.println(0);
}
}
private static int lca(int a, int b) {
if (depth[a] < depth[b]) return lca(b, a);
//a要在b的上面
//depth[a]>depth[b]也就是a的深度更深,a在下面
//a往上跳,先跳到根b相同高度
for (int k = 17; k >= 0; k--) {
if (depth[up[a][k]] >= depth[b]) {
a = up[a][k];
}
}//从高往低跳
}//跳到一个特别高的位置,会使得up[a][k]=0,而0是不存在的节点,depth[0]=0,不会出错
//从高往下跳,最终a与b处于同一高度
if (a == b) return a;
//a与b处于同一高度,从高往低枚举,同时跳
for (int k = 17; k >= 0; k--) {
if (up[a][k] != up[b][k]) {
a = up[a][k];
......@@ -127,4 +129,6 @@ public class 祖孙询问 {
}
}
}
}
package String;
/**
* KMP解决单模式串,AC自动机=trie+kmp 可以解决多模式串
*/
public class AC自动机 {
}
package String;
import java.util.Arrays;
import java.util.Scanner;
/**
* https://blog.csdn.net/qq_30277239/article/details/100881221
* <p>
* T是匹配串,P是模式串
* 假设T[s+1,...s+k]和P[1..k]匹配上了,
* 此时T[s+k+1]!=P[k+1]
* 朴素的做法是回到T[s+2]的位置,和P[1]的位置重新开始比较,
* KMP找到一个最大的x,使得T[s+1,...s+k]的后x个字符和P的前x的字符相同
* 这部分就是可以匹配上的,O(n+m)
* 又注意到,T[s+1...s+k]=P[1..k]
* 那么我们要求就是一个最大的x,满足P[1..k]的前x个字符,等于它的后x个字符,当然x要小于k
* 这个x记为next[k],这个只与模式串有关
* <p>
* 样例
* 3
* aba
* 5
......@@ -17,12 +28,11 @@ public class KMP {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
p = sc.next().toCharArray();
p = sc.next().toCharArray();//长度为n的模式串
m = sc.nextInt();
a = sc.next().toCharArray();
a = sc.next().toCharArray();//长度为m的文本串
int i = 0, j = 0;
init();
System.out.println(Arrays.toString(ne));
//i是源串,j是匹配串
while (i < m && j < n) {
if (j == -1 || a[i] == p[j]) {
......@@ -31,7 +41,7 @@ public class KMP {
j++;
} else j = ne[j];//回到适配位置
if (j == n) {//匹配成功!找到了
j = ne[j];
j = ne[j];//又开始找下一个
System.out.println(i - n);
//找到每个匹配成功的起始位置
}
......@@ -52,5 +62,4 @@ public class KMP {
ne[i] = t + 1;
}
}
}
package String;
/**
* 给定两个字符串S和T(长度分别为n和m)
* 定义extend[i]=S[i..n]与T的最长公共前缀的长度
* 求extend数组
* i 1 2 3 4 5 6 7
* S a b a b a c a
* T a b a c
* extend[i] 3 0 4 0 1 0 1
* 如果S==T那么extend就是Z数组
*/
public class 拓展kmp {
public static void main(String[] args) {
}
}
package String;
import java.io.*;
import java.util.StringTokenizer;
public class 洛谷kmp {
public static void main(String[] args) throws IOException {
a = next().toCharArray();
p = next().toCharArray();
init();
int i = 0, m = a.length, j = 0, n = p.length;
while (i < m && j < n) {
if (j == -1 || p[j] == a[i]) {
i++;
j++;
} else j = ne[j];
if (j == n) {
bw.write(i - j + 1 + "\n");
j = ne[j];
}
}
for (int k = 1; k <= p.length; k++) {
bw.write(ne[k] + " ");
}
bw.flush();
}
private static void init() {
ne[0] = -1;
int t = 0;
for (int i = 1; i <= p.length; i++) {
t = ne[i - 1];
while (t != -1 && p[i - 1] != p[t]) t = ne[t];
ne[i] = t + 1;
}
}
static int[] ne = new int[1000];
static char[] p;
static char[] a;
static int n;
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tk = new StringTokenizer("");
static String next() throws IOException {
while (!tk.hasMoreTokens()) {
tk = new StringTokenizer(br.readLine());
}
return tk.nextToken();
}
}
......@@ -33,7 +33,7 @@ import java.util.StringTokenizer;
* 1
* 设A1 A2...An
* 倒着往前推,
* 那么An位置,就是第An+1小的数
* 那么An位置,就是第An+1小的数
* 第A(i)位置,有A(i)头比它少,就是剩下的第A(i)小的数
* (1)从剩余的数中找到第k小的数
* (2)删除某个数
......@@ -63,7 +63,7 @@ public class 谜一样的牛 {
add(r, -1);
}
for (int i = 1; i <= n; i++) {
bw.write(ans[i]+"\n");
bw.write(ans[i] + "\n");
}
bw.flush();
......
......@@ -27,15 +27,13 @@ public class seg {
}
static class node {
int l, r;
long sum;//区间和
int lazy;//懒标记,给当前节点为根的子树中的每一个节点加上lazy(设计不包含根节点)
//只要递归到子区间就pushdown
int l, r, lazy;
long v;
public node(int l, int r, int sum) {
public node(int l, int r, long v) {
this.l = l;
this.r = r;
this.sum = sum;
this.v = v;
}
}
......@@ -52,44 +50,44 @@ public class seg {
}
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);
tr[k].v = tr[k << 1].v + tr[k << 1 | 1].v;
}
static long query(int k, int l, int r) {
if (tr[k].l >= l && tr[k].r <= r) {
return tr[k].sum;
return tr[k].v;
}
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;
long res = 0;
if (l <= mid) res += query(k << 1, l, r);
if (r > mid) res += query(k << 1 | 1, l, r);
return res;
}
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 << 1].v += (tr[k << 1].r - tr[k << 1].l + 1) * tr[k].lazy;
tr[k << 1 | 1].v += (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 void update(int k, int l, int r, int d) {
if (tr[k].l >= l && tr[k].r <= r) {
tr[k].v += (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 int N = (int) (1e5 + 2), n, m;
static node[] tr = new node[N * 4];
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
......
package 线段树;
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
import static java.lang.System.in;
/**
* 不能用废弃
* https://www.acwing.com/blog/content/487/
* 静态区间第k大
* 我们可以建立一颗权值线段树,每个点存储的信息为该值域区间存在的数的个数。
*/
public class 静态主席树结点版本 {
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());
}
static class seg {
int l, r, v;
public seg(int l, int r, int v) {
this.l = l;
this.r = r;
this.v = v;
}
}
static seg[] tr = new seg[200100 * 20];
public static void main(String[] args) throws IOException {
n = nextInt();
m = nextInt();
for (int i = 1; i <= n; i++) {
a[i] = nextInt();
d[i] = a[i];
}
Arrays.sort(d, 1, n + 1);
int len = unique(d, n);
for (int i = 1; i <= n; i++) {
a[i] = Arrays.binarySearch(d, 1, 1 + len, a[i]);
}
T[0] = build(1, len);
int l, r, k;
while (m-- != 0) {
l = nextInt();
r = nextInt();
k = nextInt();
int ans = query(T[l - 1], T[r], l, len, k);
bw.write(d[ans] + "\n");
}
bw.flush();
}
static int[] a = new int[200010];
static int[] d = new int[200010];
static int[] T = new int[200010];
static int tot = 0, n, m;
static int unique(int[] t, int n) {
int j = 1;
for (int i = 1; i <= n; i++) {
if (j == 1 || t[i] != t[i - 1]) {
t[j++] = t[i];
}
}
return j;
}
/**
* 建树,
*
* @param l 左区间
* @param r
* @return 根节点位置
*/
static int build(int l, int r) {
int p = ++tot, mid = l + r >> 1;
tr[p] = new seg(l, r, 0);
if (l < r) {
tr[p].l = build(l, mid);
tr[p].r = build(mid + 1, r);
}
return p;
}
static int update(int pre, int l, int r, int v) {
int p = ++tot, mid = l + r >> 1;
tr[p].l = tr[pre].l;
tr[p].r = tr[pre].r;
tr[p].v = tr[pre].v + 1;
if (l < r) {
//应该更新哪一个值域区间
if (v <= mid) tr[p].l = update(tr[pre].l, l, mid, v);
else tr[p].r = update(tr[pre].r, mid + 1, r, v);
}
return p;
}
static int query(int x, int y, int l, int r, int k) {
if (l == r) return l;
//对位相减
int sum = tr[tr[y].l].v - tr[tr[x].l].v, mid = l + r >> 1;
if (k <= sum) return query(tr[x].l, tr[y].l, l, mid, k);
else return query(tr[x].r, tr[y].r, mid + 1, r, k - sum);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册