杂题练习10.11

UVa1428

树状数组思博题,然鹅漏了l > mid > r的情况……我是不是该补脑了

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 100100;
const int LIM = 100000;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

#define lowbit(x) (x & -x)
int bit[MAXN], n, a[MAXN];

void update(int x, int y) {
	for( ; x <= LIM; x += lowbit(x)) bit[x] += y;
}

int query(int x) {
	int ret = 0;
	for( ; x; x -= lowbit(x)) ret += bit[x];
	return ret;
}

int L[MAXN], R[MAXN], L2[MAXN], R2[MAXN];

void solve() {
	read(n);
	memset(bit, 0, sizeof(bit));
	for(int i = 1; i <= n; i++) {
		read(a[i]);
		L[i] = query(a[i] - 1);
		L2[i] = i - 1 - L[i];
		update(a[i], 1);
	}
	memset(bit, 0, sizeof(bit));
	for(int i = n; i; i--) {
		R[i] = query(LIM) - query(a[i]);
		R2[i] = (n - i - R[i]);
		update(a[i], 1);
	}
	long long ans = 0;
	for(int i = 2; i < n; i++) ans += (long long) L[i] * (long long) R[i];
	for(int i = 2; i < n; i++) ans += (long long) L2[i] * (long long) R2[i];
	printf("%lld\n", ans);
}

int T;
 
signed main() {
	read(T);
	while(T--) {
		solve();
	}
	return 0;
}

UVa11235

蜜汁RMQ,xjb维护一下同一个值的区间长度,特判l r是同一个值的情况和l r是相邻区间的情况

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 100100;
const int MAXE = 400400;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

int f[MAXN][19], a[MAXN], n, Q;
int belong[MAXN], l[MAXN], r[MAXN], cnt, len[MAXN];

void update() {
	for(int i = 1; i <= cnt; i++) f[i][0] = len[i];
	for(int j = 1; (1 << j) <= cnt; j++) {
		for(int i = 1; i + (1 << j) - 1 <= cnt; i++) {
			f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
		}
	}
}

int query(int x, int y) {
	int p = 0; while((1 << (p + 1)) <= (y - x + 1)) p++;
	return max(f[x][p], f[y - (1 << p) + 1][p]);
}
 
signed main() {
	read(n);
	if(n == 0) return 0;
	read(Q);
	for(int i = 1; i <= n; i++) read(a[i]);
	for(int i = 1; i <= n; i++) {
		if(a[i] != a[i - 1] || i == 1) {
			r[cnt] = i - 1;
			len[cnt] = r[cnt] - l[cnt] + 1;
			l[++cnt] = i;
			belong[i] = cnt;
			continue;
		}
		belong[i] = cnt;
	}
	r[cnt] = n, len[cnt] = n - l[cnt] + 1;
	update();
	while(Q--) {
		int x, y;
		read(x), read(y);
		if(belong[x] == belong[y]) {
			printf("%d\n", y - x + 1);
			continue;
		}
		int L = r[belong[x]] - x + 1;
		int R = y - l[belong[y]] + 1;
		x = belong[x] + 1;
		y = belong[y] - 1;
		if(x > y) {
			printf("%d\n", max(L, R));
			continue;
		}
		int ans = L;
		CheckMax(ans, R);
		CheckMax(ans, query(x, y));
		printf("%d\n", ans);
	}
	main();
}

UVa1513

开双倍空间,将初始数组插入到MAXN + 1到MAXN + n,之后的操作按题意模拟,用树状数组维护前缀和即可

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 200200;
const int LIM = 100002;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

#define lowbit(x) (x & -x)
int bit[MAXN], n, a, Q, T, cnt = LIM - 1, pos[MAXN >> 1];

void update(int x, int y) {
	for( ; x < MAXN; x += lowbit(x)) bit[x] += y;
}

int query(int x) {
	int ret = 0;
	for( ; x; x -= lowbit(x)) ret += bit[x];
	return ret;
}
 
signed main() {
	read(T);
	while(T--) {
		read(n); read(Q);
		cnt = LIM - 1;
		memset(bit, 0, sizeof(bit));
		for(int i = 1; i <= n; i++) update(LIM + i, 1);
		for(int i = 1; i <= n; i++) pos[i] = LIM + i;
		for(int i = 1; i <= Q; i++) {
			read(a);
			printf("%d%c", query(pos[a] - 1), i == Q ? '\n' : ' ');
			update(pos[a], -1);
			pos[a] = cnt--;
			update(pos[a], 1);
		}
	}
	return 0;
}

UVa12299

线段树/树状数组板题,按题意模拟即可……最难的地方居然是输入

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 100100;
const int MAXE = 400400;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

struct SegmentTree {
	int l, r, mn;
	SegmentTree(int _l = 0, int _r = 0, int _mn = 0) : l(_l), r(_r), mn(_mn) {}
}tre[MAXE]; 

#define Ls(x) x << 1
#define Rs(x) x << 1 | 1

int n, Q, a[MAXN];
char s[35];
int opt[35], num[35];

void push_up(int x) {
	tre[x].mn = min(tre[Ls(x)].mn, tre[Rs(x)].mn);
}

void build(int x, int l, int r) {
	tre[x].l = l, tre[x].r = r;
	if(l == r) {
		tre[x].mn = a[l];
		return ;
	}
	int mid = (l + r) >> 1;
	build(Ls(x), l, mid);
	build(Rs(x), mid + 1, r);
	push_up(x);
}

void update(int x, int pos, int val) {
	int l = tre[x].l, r = tre[x].r;
	if(l == r) {
		tre[x].mn = val;
		return ;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid) update(Ls(x), pos, val);
	else update(Rs(x), pos, val);
	push_up(x);
}

int query(int x, int L, int R) {
	int l = tre[x].l, r = tre[x].r;
	if(r < L || l > R) return INF;
	if(L <= l && r <= R) return tre[x].mn;
	int Min = INF;
	CheckMin(Min, query(Ls(x), L, R));
	CheckMin(Min, query(Rs(x), L, R));
	return Min;
}

int get_number(char * str) {
    int dex = 0;
    int len = (int) strlen(str);
    opt[dex] = 0;
    bool flag = 0;
    for(int i = 0; i < len; i++) {
        if(isdigit(str[i])) {
            opt[dex] = opt[dex] * 10 + str[i] - '0';    
            flag = 1;
        } 
		else if(flag) opt[++dex] = 0;
    }
    return dex;
}
 
signed main() {
	read(n), read(Q);
	for(int i = 1; i <= n; i++) read(a[i]);
	build(1, 1, n);
	while(Q--) {
		scanf("%s", s);
		int len = get_number(s);
		if(s[0] == 'q') {
			printf("%d\n", query(1, opt[0], opt[1]));
		}
		else {
			for(int i = 0; i < len; i++) num[i] = a[opt[i]];
            for(int i = 0; i < len; i++) {
                if(i + 1 < len) a[opt[i]] = num[i + 1];
                else a[opt[i]] = num[0];
                update(1, opt[i], a[opt[i]]);
            }
		}
	}
	return 0;
}

 

Java黑皮书课后习10.11要求我们编写一个程序,该程序在一个二维数组中查找是否存在一个指定的值。如果存在,则返回该值的位置(行和列),否则返回(-1, -1)。 首先,我们需要创建一个二维数组,并初始化它。然后,通过遍历数组的每个元素来查找指定值。当找到指定值时,记录其位置并返回。 以下是解思路: 1. 创建一个名为findValue的方法,参数为一个二维整数数组和一个整数值。 2. 在方法内,使用两个嵌套的for循环遍历数组的每个元素,外层循环控制行,内层循环控制列。 3. 在每次循环中,检查当前元素是否等于指定值。如果是,返回当前位置(row, column)。 4. 如果遍历完整个数组都没有找到指定值,返回位置(-1, -1)。 以下是代码示例: ```java public class Main { public static void main(String[] args) { // 创建二维数组 int[][] array = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; int target = 5; // 指定值 // 调用findValue方法查找指定值的位置 int[] position = findValue(array, target); // 输出结果 if (position[0] == -1 && position[1] == -1) { System.out.println("指定值不存在!"); } else { System.out.println("找到指定值,位置为(" + position[0] + ", " + position[1] + ")"); } } public static int[] findValue(int[][] array, int target) { for (int row = 0; row < array.length; row++) { for (int column = 0; column < array[row].length; column++) { if (array[row][column] == target) { return new int[]{row, column}; } } } return new int[]{-1, -1}; } } ``` 以上代码会输出"找到指定值,位置为(1, 1)",即指定值5在二维数组的第2行第2列。如果指定值不在数组中,则输出"指定值不存在!"。 希望这个回答对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值