考试时题面用pdf格式给却不是latex生成的,严重吐槽
今天bzoj好像出事了。。
给你N个数,编号1~N,从某个区间[L,R]中,任意选择二个数字,它们相同的概率是多少。
第一行一个整数N
接下来一行,N个整数。
第三行一个整数M,表示询问次数。
接下来M行,每行两个整数L,R
M行,每行一个分数,表示两个数字是相同的概率,必须为最简分数。
6 4
1 2 3 3 3 2
2 6
1 3
3 5
1 6
2/5
0/1
1/1
4/15
40%: n,m≤500
60%: n,m≤5000
100%: n,m≤50000
实际上是 BZOJ 2038…
http://www.lydsy.com/JudgeOnline/problem.php?id=2038
到时再新开帖子贴题解吧。。
另外吐槽欢乐赛出题人(好像哪里不对),强行改样例不改数据。好懒(好像就在说我)。
而且数据很水 O(n2) 的暴力竟然90分。。
好像数据没判断0/1和0/0。
暂时贴个暴力。。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define FOR(i,j,k) for(i=j;i<=k;i++)
#define rep(i,j,k) for(i=j;i<k;i++)
typedef long long ll;
ll read() {
ll s = 0, f = 1; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0';
return s * f;
}
const int N = 50105;
ll a[N], b[N], c[N];
ll gcd(ll a, ll b) {
if (!b) return a;
else return gcd(b, a % b);
}
int main() {
ll n, m, i, j, x, y;
n = read();
FOR(i,1,n) a[i] = b[i] = read();
sort(b + 1, b + n + 1);
FOR(i,1,n) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
m = read();
FOR(i,1,m) {
x = read(), y = read();
ll ans2 = 0, ans1 = 0;
memset(c, 0, sizeof c);
FOR(j,x,y) ans1 += j - x - c[a[j]], ++c[a[j]], ans2 += j - x;
ans1 = ans2 - ans1;
ll g = gcd(ans1, ans2);
if (g == 0) g = 1;
printf("%I64d/%I64d\n", ans1 / g, ans2 / g);
}
return 0;
}
http://blog.csdn.net/huanghongxun/article/details/50646716
有一个专门接待嘉宾的餐厅,它的营业时间是 [0,T] 时刻。餐厅有一个神奇的伸缩门,门的高度可以在 [0,K] 之间变动,而且在每个单位时间,门可以变大一个单位,也可以缩小一个单位,当然也可以不变(变动的范围不能超过边界)。
在刚开始的时候,这个门的高度为 0,意味着门是关着的。现在有 n 个贵宾要通过这扇门。每个嘉宾的身高 si 和重要度 pi ,以及到达的时间 ti 是不一样的。嘉宾将在 ti 时间到达门前,如果此时门的高度刚好等于嘉宾的身高 si 时,嘉宾才会认为这扇门是专门为他而开的,所以他才会进入餐厅。
问,怎么安排伸缩门,才能使进入餐厅的嘉宾的重要度和最大。
第一行三个整数, N, K, T
接下来 3 行。
第一行是 t1,t2,⋯,tn ,表示 1~N 嘉宾到达的时间
第二行是 p1,p2,⋯,pn ,表示嘉宾的重要度
第三行是 s1,s2,⋯,sn ,表示嘉宾的身高。
一行一个整数,表示进入餐厅的嘉宾的最大重要度之和。
4 10 20
10 16 8 16
10 11 15 1
10 7 1 8
26
1≤n,k≤100
0≤t≤30000
0≤ti≤t
0≤pi≤300
1≤si≤k
一个简单的dp。
先按时间排序嘉宾。
令 fi,j 表示轮到第 i 个嘉宾的时候,当前门的高度是 j 的最大重要度和。
那么显然有
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define FOR(i,j,k) for(i=j;i<=k;i++)
#define rep(i,j,k) for(i=j;i<k;i++)
inline int read() {
int s = 0, f = 1; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0';
return s * f;
}
inline void getmax(int &a, int b) { if (a < b) a = b; }
const int N = 128, inf = 0x7f7f7f7f;
struct Person {
int t, p, s;
bool operator< (const Person &b) const {
return t < b.t;
}
} p[N];
int f[N][N];
int main() {
int n = read(), k = read(), t = read(), i, j, c, q, ans = 0;
FOR(i,1,n) p[i].t = read();
FOR(i,1,n) p[i].p = read();
FOR(i,1,n) p[i].s = read();
sort(p + 1, p + n + 1);
FOR(i,1,n) if (p[i].t > t) n = i - 1;
FOR(i,1,k) f[0][i] = -inf;
f[0][0] = 0;
FOR(i,1,n) FOR(j,1,k) {
q = j == p[i].s ? p[i].p : 0;
f[i][j] = -inf;
FOR(c,0,min(k,p[i].t-p[i-1].t)) {
if (j+c<=k) getmax(f[i][j], f[i-1][j+c] + q);
if (j-c>=0) getmax(f[i][j], f[i-1][j-c] + q);
}
}
FOR(j,1,k) getmax(ans, f[n][j]);
printf("%d", ans);
return 0;
}
给定一个正整数序列,总共有 N 个数。问逆序数是多少?逆序数为逆序对的个数。逆序对的定义:假如一个正整数序列为 1,3,4,2,5.则逆序数为 2.
因为 3, 2 构成一个逆序对, 4, 2 构成一个逆序对。当排在前面的数字大于后面的某个数字时,则这两个数字构成一个逆序对。
第一行一个正整数 N
接下来 N 个正整数,表示这个正整数序列。
一行一个正整数,表示逆序数。
6
1 3 2 6 5 4
4
样例:(3,2),(6,5),(6,4),(5,4)。
50%: n≤1000
100%: n≤100000
逆序对裸题(输入法好坑啊)。。。。。。。
我选择树状数组233。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define FOR(i,j,k) for(i=j;i<=k;i++)
#define rep(i,j,k) for(i=j;i<k;i++)
typedef long long ll;
ll read() {
ll s = 0, f = 1; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0';
return s * f;
}
const int N = 100100;
ll a[N], b[N], c[N], n;
void add(ll i, ll x) {
for (; i <= n; i += i & -i) c[i] += x;
}
ll sum(ll i) {
ll s = 0;
for (; i; i -= i & -i) s += c[i];
return s;
}
int main() {
ll i, ans = 0;
n = read();
FOR(i,1,n) a[i] = b[i] = read();
sort(b + 1, b + n + 1);
FOR(i,1,n) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
FOR(i,1,n) {
ans += sum(n) - sum(a[i]);
add(a[i], 1);
}
printf("%I64d", ans);
return 0;
}
没能AK真是可惜。
莫队忘了还得复习(腹泻)。