A

考虑分步做合成 coal 和合成 craft 。发现我们做 $n$ 次替换后拥有的 stick 数量是 $nx-n+1$,首先要凑出 $k$ 个 coal,然后还要剩下来 $k$ 个 stick 合成,所以我们造 stick 的限制就有 $nx-n+1 \geq ky+k$,这样 $n$ 就是交易 stick 用掉的次数了,再加上 $k$(交易 coal 的次数)

B

把未被锁定的位置从大到小排序即可。因为无论如何放最后一个未锁定的位置的前缀和不会变,那么肯定先把所有最大的都用上去尽量 cover 掉小的贡献。

C

dp。设 $f_{i,0/1}$ 表示打了前 $i$ 关,轮到玩家还是玩家的朋友打的最小代价,直接枚举转移即可。

D

假设两个位置选择的分别是 $x_1,x_2(x_1 < x_2)$,把坐标排好序后肯定存在一个分解点 $mid$,满足 $i \leq mid$ 都走到 $x_1$,并且 $i > mid$ 都走到 $x_2$。设第 $i$ 个坐标位置 $p_i$,发现这样的代价为 $p_n-p_1-(p_{mid+1}-p_{mid})$,所以实际上是要你支持插入,删除,维护相邻差的最大值,用两个 multiset 就可以了。

E

根据期望的线性性,我们只需要计算每一个 boss 对玩家的期望伤害即可。

boss 可以分为两类:一类是会削玩家护盾耐久的,一类是螳臂当车的。

对于会削玩家护盾耐久的,设这样的 boss 有 $m$ 个,能打到玩家的概率是 $\frac{m-a_i}{m}$(因为它在这 $m$ 个数的相对排名只有 $m$ 种情况,后面 $m-a_i$ 种是合法的)

对于螳臂当车的 boss,设这样的 boss 有 $k$ 个,能打到玩家的概率是 $\frac{m+1-a_i}{m+1}$。(因为它只能选择 $m+1$ 个空插进去,后面 $m+1-a_i$ 个空是合法的)

分开乘起来就行。多组询问只需要离线排序,变成了维护每次将一个削玩家耐久的变成螳臂当车的boss的操作,记录一下权值和就行了。

F

发现一个结论:对于任何一对 $x_1y_1 = x_2y_2(x_1 < x_2)$,都存在一对正整数 $a < b$,满足 $x_2 = \frac{x_1}{a}b,y_2 = \frac{y_1}{b}a$。

证明


设 $g=\gcd(x_1,x_2)$,我们构造 $a=\frac{x_1}{g},b = \frac{x_2}{g}$,不难发现 $\frac{x_1}{a}b = x_2$,接下来只需要证明 $b|y_1$即可。注意到 $b=\frac{x_2}{g} | \frac{x_2y_2}{g} = \frac{x_1y_1}{g}$,又因为有 $(b,\frac{x_1}{g}) = 1$,所以得到 $b|y_1$。

因为 $a|x_1,b|y_1$,所以有效的 $(a,x_1)$ 只有 $O(n \log n)$ 对。

现在我们去固定 $x_1$,考虑 $y_1$ 的种种限制:首先要保证 $y_1 \leq m$,其次还要保证 $\lceil \frac{L}{x_1}\rceil \leq y_1 \leq \lfloor \frac{R}{x_1} \rfloor$。

我们考虑枚举一对 $(a,x_1)$,现在相当于要求快速询问是否存在一对 $(b,y_1)$ 满足如下条件:

$$ \begin{aligned} y_1 \leq m\\ \lceil \frac{L}{x_1}\rceil \leq y_1 \leq \lfloor \frac{R}{x_1} \rfloor\\ \frac{x_1}{a}b \leq n\\ a < b \end{aligned} $$

显然我们会贪心选择能选择的 $b$ 中最小的去判断第三个限制是否成立。

第一个和第二个限制可以通过从小到大枚举 $x$ 双指针解决,第四个限制可以维护当前所有可选值的 set 解决,复杂度 $O(n \log^2 n)$。

G

确定性做法

我们考虑枚举右端点,维护每个左端点是否合法。

我们的目标是让对于每一种颜色,如果左端点区间是合法的,贡献就是 $0$,否则贡献是 $1$。

那么一个左端点合法当且仅当这个位置的值是 $0$。

我们每次加入一个点 $i$,设它前面第一个,第二个,第三个,第四个和它相等的是 $p_1,p_2,p_3,p_4$,我们只需要让 $(p_1,i]+1$,$(p_3,p_2]-1$,$(p_4,p_3]+1$ 即可。

线段树维护最小值和最小值个数,支持区间加即可。

基于这个做法我把题目小小加强了一下链接(不确定正确性

详细维护方式可以见代码:

#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 5e5 + 5;
int a[MAXN],n;
#define lc ((x)<<1)
#define rc ((x)<<1|1)

int mn[MAXN<<2],cnt[MAXN<<2],tag[MAXN<<2];

inline void pushup(int x){
    mn[x] = std::min(mn[lc],mn[rc]);cnt[x] = 0;
    if(mn[x] == mn[lc]) cnt[x] += cnt[lc];
    if(mn[x] == mn[rc]) cnt[x] += cnt[rc];
}

inline void cover(int x,int d){
    mn[x] += d;tag[x] += d;
}

inline void pushdown(int x){
    if(tag[x]){
        cover(lc,tag[x]);
        cover(rc,tag[x]);
        tag[x] = 0;
    }
}

inline void modify(int x,int l,int r,int L,int R,int d){
    if(L > R) return;
    if(l == L && r == R){
        cover(x,d);return;
    }
    int mid = (l + r) >> 1;pushdown(x);
    if(R <= mid) modify(lc,l,mid,L,R,d);
    else if(L > mid) modify(rc,mid+1,r,L,R,d);
    else modify(lc,l,mid,L,mid,d),modify(rc,mid+1,r,mid+1,R,d);
    pushup(x);
}

inline void build(int x,int l,int r){
    if(l == r){
        cnt[x] = 1;mn[x] = 1e9;return;
    }
    int mid = (l + r) >> 1;
    build(lc,l,mid);build(rc,mid+1,r);
    pushup(x);
}

int lst[MAXN],pre[MAXN];

int main(){
    scanf("%d",&n);
    FOR(i,1,n) scanf("%d",a+i);
    FOR(i,1,n){
        pre[i] = lst[a[i]];
        lst[a[i]] = i;
    }
    build(1,1,n);LL ans=  0;
    FOR(i,1,n){
        int p1 = pre[i],p2 = pre[p1],p3 = pre[p2],p4 = pre[p3];
        modify(1,1,n,i,i,-1e9);
        modify(1,1,n,p1+1,i,1);
        if(p2) modify(1,1,n,p3+1,p2,-1);
        if(p3) modify(1,1,n,p4+1,p3,1);
        if(mn[1] == 0) ans += cnt[1];
    }
    printf("%lld\n",ans);
    return 0;
}

基于随机的做法

出现三次不难联想到三进制不进位加法。我们对于每个数字随机一个 $60$ 维模 $3$ 意义下的向量,前缀和后两个位置前缀和相同就表示这一段区间所有出现次数 $\bmod 3=0$,但是我们想要的是 $=3$,我们只需要用双指针维护出满足所有颜色出现次数 $\leq 3$ 的区间即可。

出题人说:

Assume you use $K$ trits. I guess the probability of the collision is the same as two vectors (out of $n$) colliding in a $K$ - dimensional space with their coordinates being from $0$ to $2$. That will be about $\frac{1}{2}$ when $n≈3^K$ (according to birthday paradox) — and way less if we increase $K$.

Last modification:March 31st, 2021 at 04:43 pm
如果觉得我的文章对你有用,请随意赞赏