CSP模拟-10

全是期望,这是捅期望窝了????
emmm.......今天考试爆炸,QAQ心态直接炸

T1 Because

等等,这是。。。。。游走?!?!!!!窝似沙币,没记住之前的题。。。。

当我打完模拟赛后:沃日,不tm的是游走,是一个再简单不过的概率题,差不多学过高一下概率单元的人都会的题,我不会!!!!!!!想死的心都有了。所以我又没有读懂题。。。我真服了。。。

首先,有 1n 的概率选到最中间的点,则选到这个点时的期望是 1n。有另外 n1n 的概率选到菊花图周围的点,在我们此时选到的除了这个点外的点中有 1n1 的概率选到中心的点,此时期望为 n1n1n1 ;我们这时选到除本个点以外的周围点的概率是 n2n1,期望为 n1n2(n2)n1。所以三个式子相加为 2n2n。注意特判点数为 2 的情况。

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
int t, n;
int main() {
cin >> t;
while (t --) {
cin >> n;
if (n == 2) {
printf("1.000000000 1.000000000\n");
}
else {
printf("%.9lf 2.000000000\n", ((double)n * 2.0 - 2.0) / ((double)n));
}
}
return 0;
}

T2 Love

其实说实话这个题真不难,但我从来没有捞到过分,也许是我太菜了吧

将所有输入的元素记录,并记录输入的元素在哪个集合,然后将所有输入的元素按数值升序排序。用双指针维护一个最小区间使其集合个数刚好小于 k,在每次左指针右移(也就是现在双指针包含的元素的集合个数超过 k)时更新 ans 值。

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
int k, n, ans = 2000000000;
int barrel[1000100], set_num;
struct Number {
int pos, num;
bool operator < (const Number &b) const {
return num < b.num;
}
}c[4001000];
int main() {
scanf("%d", &k);
for (int i = 1, sum; i <= k; ++ i) {
scanf("%d", &sum);
for (int j = 1 + n; j <= sum + n; ++ j) {
scanf("%d", &c[j].num);
c[j].pos = i;
}
n += sum;
}
sort(c + 1, c + 1 + n);
for (int l = 1, r = 1; r <= n; ++ r) {
if (barrel[c[r].pos] == 0)
set_num ++;
barrel[c[r].pos] ++;
while (set_num == k) {
if (set_num == k) {
ans = min(ans, c[r].num - c[l].num);
}
if (barrel[c[l].pos] == 1) {
set_num --;
}
barrel[c[l].pos] --;
l ++;
}
}
cout << ans << endl;
return 0;
}

T3

T4 Everyday

题目要输出的是选出的宝石的值的种类有多少种

将每段区间直接硬并,如若输入 ai=1,bi=3ai+1=2,bi+1=4 合并后是a1=1,b1=3a2=2,b2=4a3=0,b3=0a4=3,b4=7。第一个序列是之选 ai,bi,第二个序列是只选 ai+1,bi+1,第三个序列是都不选,第四个序列是都选。用线段树维护在 l,r 的宝石序列所构成的集合就行。

时间复杂度,因为是随的,所以基本上线段树上每个节点是 O(1) 的范围,不会炸

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
long long n, q;
long long opt, k, a, b, L, R, sum;
pair<long long, long long> interval[310000];
vector <pair<long long, long long> > ASK;
struct Segment_Tree {
long long l, r;
vector <pair<long long, long long> > vec;
}tree[300000];
struct SegmentTree {
#define lid id << 1
#define rid id << 1 | 1
vector<pair<long long, long long> > Pushup(vector<pair<long long, long long> > &l, vector<pair<long long, long long> > &r) {
//硬并,将l和r里面的集合一个一个对应相加
pair <long long, long long> tem1, tem2;
vector<pair<long long, long long> > now, ans;
for (int i = 0; i < (int)l.size(); ++ i) {
for (int j = 0; j < (int)r.size(); ++ j) {
tem1 = l[i], tem2 = r[j];
now.push_back(make_pair(tem1.first + tem2.first, tem1.second + tem2.second));
}
}
now.shrink_to_fit();
bool flag[now.size()];
for (int i = 0; i < (int)now.size(); ++ i) {
flag[i] = false;
}
sort(now.begin(), now.end());
//排序后合并now内有重叠的区间
for (int i = 1; i < (int)now.size(); ++ i) {
tem1 = now[i - 1], tem2 = now[i];
if (tem1.first <= tem2.first && tem2.first <= tem1.second) {
tem1.second = max(tem1.second, tem2.second);
if (flag[i - 1] == true) {
ans.pop_back();
flag[i - 1] = false;
}
ans.push_back(tem1);
now[i] = tem1;
flag[i] = true;
}
else {
if (flag[i - 1] == false) {
ans.push_back(tem1);
flag[i - 1] = true;//
}
ans.push_back(tem2), flag[i] = true;
}
}
ans.shrink_to_fit();
return ans;
// for (set<pair<long long, long long> >::iterator it1 = tree[lid].Set.begin(); it1 != tree[lid].Set.end(); it1 ++) {
// for (set<pair<long long, long long> >::iterator it2 = tree[rid].Set.begin(); it2 != tree[rid].Set.end(); it2 ++) {
// tem1 = *it1, tem2 = *it2;
// tem1.first = tem1.first + tem2.first;
// tem1.second = tem1.second + tem2.second;
// tree[id].Set.insert(tem1);
// }
// }
// pair<long long, long long> *las, *now;
// for (set<pair<long long, long long> >::iterator it = tree[id].Set.begin(); it != tree[id].Set.end(); ++ it) {
// if (it == tree[id].Set.begin()) continue;
// las = *prev(it);
// }
}
void BuildTree(int id, int l, int r) {
tree[id].l = l, tree[id].r = r;
if (l == r) {
tree[id].vec.push_back(make_pair(0, 0));
tree[id].vec.push_back(interval[l]);
//注意要后插interval,因为后面修改的时候要弹出interval
return;
}
int mid = l + ((r - l) >> 1);
BuildTree(lid, l, mid);
BuildTree(rid, mid + 1, r);
tree[id].vec = Pushup(tree[lid].vec, tree[rid].vec);
tree[id].vec.shrink_to_fit();
//正常建树
return;
}
void Update(int id, int l, int r, int pos, pair<long long, long long>upd) {
if (l == r) {
tree[id].vec.pop_back();
tree[id].vec.push_back(upd);
//更新弹出后在插入
return;
}
int mid = l + ((r - l) >> 1);
if (pos <= mid) Update(lid, l, mid, pos, upd);
else Update(rid, mid + 1, r, pos, upd);
tree[id].vec.clear();
tree[id].vec = Pushup(tree[lid].vec, tree[rid].vec);
//pushup
tree[id].vec.shrink_to_fit();
return;
}
vector<pair<long long, long long> > Query(int id, int l, int r, int ask_l, int ask_r) {
if (ask_l <= l && r <= ask_r) {
return tree[id].vec;
}
int mid = l + ((r - l) >> 1);
vector<pair<long long, long long> > tem1, tem2, ask;
tem1.push_back(make_pair(0, 0)), tem2.push_back(make_pair(0, 0));
//注意初始化
if (ask_l <= mid) tem1 = Query(lid, l, mid, ask_l, ask_r);
if (mid + 1 <= ask_r) tem2 = Query(rid, mid + 1, r, ask_l, ask_r);
return Pushup(tem1, tem2);
}
}Tree;
int main() {
scanf("%lld%lld", &n, &q);
for (int i = 1; i <= n; ++ i) {
scanf("%lld%lld", &a, &b);
interval[i] = make_pair(a, b);
}
Tree.BuildTree(1, 1, n);
while (q --) {
scanf("%lld", &opt);
if (opt == 1) {
scanf("%lld%lld%lld", &k, &a, &b);
Tree.Update(1, 1, n, k, make_pair(a, b));
}
else {
scanf("%lld%lld", &L, &R);
ASK = Tree.Query(1, 1, n, L, R);
for (int i = 0; i < (int)ASK.size(); ++ i) {
sum += (ASK[i].second - ASK[i].first + 1);
}
cout << sum << endl;
sum = 0;
}
}
return 0;
}
posted @   觉清风  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示