杂题练习10.11

版权声明:博主是菜鸡,但转的时候还是说一声吧 https://blog.csdn.net/qq_37666409/article/details/83187391

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;
}

猜你喜欢

转载自blog.csdn.net/qq_37666409/article/details/83187391