20180805 提高Day2 模拟赛

题目目录

  1. 主席树
  2. 决斗
  3. 钦点

主席树

题意

给定序列 $A$ ,你需要将 $A$ 中所有长度 $\geq k$ 的子区间中每一个子区间的第 $\mathbf{k}$ 的元素提出来组成序列 $B$,然后输出 $B$ 序列中的第 $\mathbf{l}$ 的元素。$n \leq 100000, A_i \leq 10^8$ 。

题解

这道题和这道题有相同之处。

我们考虑二分答案 $x$ ,将 $A$ 中所有 $\leq x$ 的元素记为 $0$ ,其他记为 $1$ 。

然后,我们用双指针统计被放到 $B$ 中的 $0$ 的个数——如果一个合法区间里有 $\geq k$ 个 $0$ ,那么它会对答案贡献一个 $0$ 。

调试记录

  • 双指针开始的时候向右偏移的元素多了一个
  • 二分写错了。。。

代码

#include <bits/stdc++.h>
using namespace std;

#define fin cin
#define fout cout

typedef long long ll;
#define int long long
int n, k, l, b[100005], A[100005];
struct node {
    int v, id;
    bool operator< (const node&res)const { return v < res.v; }
} a[100005];

bool check(int x, ll tot) {
    int pre = 0;
    for (int i=1; i<=n; i++) if (A[i] <= x) b[pre] = i, pre = i;
    b[pre] = n+1;
    ll ret = 0, lst = 0, cur = b[0], r=cur;
    for (int i=1; i<k && r!=n+1; i++) r = b[r];
    if (r == n+1) {
        return tot < ::l;
    }
    do {
        ret += 1ll * (cur-lst) * (n-r+1);
        lst = cur; cur = b[cur]; r = b[r];
    } while (r != n+1);
    return tot - ret < l;
}

signed main() {
    ios :: sync_with_stdio(false);
    fin >> n >> k >> l;
    for (int i=1; i<=n; i++) fin >> a[i].v, a[i].id = i;
    sort(a+1, a+1+n);
    int m=1; A[a[1].id]=1; for (int i=2; i<=n; i++) {
        if (a[i].v != a[i-1].v) ++m;
        A[a[i].id] = m;
    }
    int l=1, r=m; ll tot = 1ll*(n-k+2)*(n-k+1); tot>>=1ll;
    while (l<r) {
        int mid = l + r >> 1;
        bool ret = check(mid, tot);
        if (check(mid, tot)) r=mid;
        else l=mid+1;
    }
    a[0].v = -1e9; int now = 0;
    for (int i=1; i<=n; i++) if (a[i].v != a[i-1].v) {
         if (++now == l) {
             fout << a[i].v << endl;
             return 0;
         }
    }
    return 233;
}

决斗

题意

两个人,每个人有血量。每个人攻击时会对对方等概率地产生 $l$ 到 $r$ 的伤害(伤害为整数)。

两个人的 $l,r$ 不同。第一个人先攻击,求第一个人获胜的概率。

题解

$f_{i,j,k}$ 表示当前状态下第一个人剩余血量为 $i$,第二个人剩余血量为 $j$ ,当前先手为 $k$ 的概率。

$k=0$:$f_{i,j,k}=\left(f_{i+l2,j,k^1}+f_{i+l2+1,j,k^1}+\cdots+f_{i+r2,j,k^1}\right)/\left(r_2-l_2+1\right)$;

$k=1$:$f_{i,j,k}=\left(f_{i,j+l1,k^1}+f_{i,j+l1+1,k^1}+\cdots+f_{i,j+r1,k^1}\right)/\left(r_1-l_1+1\right)$;

使用前(后)缀和优化(这里使用后缀和比较方便)。

时间复杂度:$\mathcal O(n^2T)$ 。

由于玄学的原因,我超时了。。。但是用玄学优化后我还是卡进了。。有图为证:

不开玄学优化:

image

开了玄学优化:

image

调试记录

  • DP 中的一个 $\leq$ 打成了 $<$ 。

代码

#pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)
#include <bits/stdc++.h>
using namespace std;

#define fin cin
#define fout cout

typedef long double ld;
int n, yl, yr, m, sl, sr;
ld f[2][505][505];
ld sum[2][505][505];

int main() {
    ios :: sync_with_stdio(false);
    int T; fin >> T;
    while (T--) {
        fin >> n >> yl >> yr >> m >> sl >> sr;
        int ly = yr - yl + 1, ls = sr - sl + 1;
        memset(f, 0, sizeof(f)); memset(sum, 0, sizeof(sum));
        for (int i=1; i<=n; i++)
            for (int j=1; j<=m; j++) {
                if (j <= yr) f[0][i][j] += min(j-yl, 0) - min(j-yr, 0) + 1;
                (f[0][i][j] += (sum[1][i][max(j-yl, 0)] - sum[1][i][max(j-yr-1, 0)])) /= ly;
                sum[0][i][j] = sum[0][i][j-1] + f[0][i][j];
                f[1][i][j] = (sum[0][max(i-sl, 0)][j] - sum[0][max(i-sr-1, 0)][j]) / ls;
                sum[1][i][j] = sum[1][i-1][j] + f[1][i][j];
            }
        fout << fixed << setprecision(3) << f[0][n][m] << endl; 
    }
    return 0;
}
posted @ 2018-08-06 07:24  MCH__ds  阅读(155)  评论(0编辑  收藏  举报