首页 > 其他分享 >[CF1902] Educational Codeforces Round 159 A~E 题解

[CF1902] Educational Codeforces Round 159 A~E 题解

时间:2023-12-04 23:23:03浏览次数:55  
标签:Educational cout 159 题解 tr cnt long ++ int

[CF1902] Educational Codeforces Round 159 A~E 题解

A. Binary Imbalance

很快观察到如果有不同的相邻元素,那么一定有解,意味着如果全是 1 无解,其他有解

B. Getting Points

题面很长,可以发现,最好的偷懒方式一定是把所有的课都拖到最后几天上(真实),可以简单调整证明这样是不劣的,最后几天上的课有三种课:

  1. 完成两个任务
  2. 完成一个任务
  3. 不做任务

推推式子就出了。

void work() {
    int n, p, a, b;
    cin >> n >> p >> a >> b;
    int t = (n - 1) / 7 + 1;
    int cnt = t / 2;
    int ans = 0;
    if(cnt * (a + 2 * b) >= p) {
        cout << n - ((p + a + 2 * b - 1) / (a + 2 * b)) << '\n';
        return ;
    }
    p -= cnt * (a + 2 * b);
    ans += cnt;
    if((t % 2 == 1) && a + b >= p) {
        cout << n - 1 - cnt << '\n';
        return ;
    }
    else if((t % 2 == 1)) {
        ans ++;
        p -= a + b;
    }
    cout << n - ans - ((p + a - 1) / a) << '\n';
    
    return ;
}

C. Insert and Equalize

考虑如果不加入新元素是什么情况。

那么最后一定会等于最大数,否则可以同时减去 \(x\) 这样更优。

那么这个 \(x\) 就必须整除所有元素和最大数的差,取个 \(\gcd\) 即可。

考虑加入新元素,那么显然不应该使 \(x\) 变小,所以只有两种情况。

  1. \(a_{n + 1} > a_n\) 此时 \(a_{n + 1} = a_n + x\)。
  2. \(a_{n + 1} < a_n\),此时 \(a_{n + 1} = a_n - kx\),\(k\) 是使得 \(a_{n + 1}\) 不重复的最小的正整数。

取 \(\min\) 即可。

void work() {
    cin >> n;
    s.clear();
    for(int i = 1; i <= n; i ++) cin >> a[i], s.insert(a[i]);
    if(n == 1) { // 要读完 a1 再return 不然会吃两发罚时
        cout << 1 << '\n';
        return ;
    }
    sort(a + 1, a + n + 1);
    int ans = 0, d = a[2] - a[1];
    for(int i = 3; i <= n; i ++) {
        d = gcd(d, a[i] - a[i - 1]);
    }
    for(int i = 1; i <= n; i ++)
        ans += (a[n] - a[i]) / d;
    int pos = 1e9;
    for(int i = 1; i <= n + 1; i ++)
        if(s.find(a[n] - i * d) == s.end()) {
            pos = i;
            break;
        }
    cout << ans + min(n, pos) << '\n';
    return ;
}

D. Robot Queries

先模拟处理出 \(p_i\) 表示第 \(i\) 次执行后机器人坐标。

观察到反转操作实际上是把所有原路径上的点关于 \(p_l, p_r\) 的中点做对称,不妨把查询的 \((x, y)\) 关于中点做对称再直接查询原路径上的点,由对称性,这样是等价的。

所以我们现在需要维护在 \([l, r]\) 时刻,\((x, y)\) 是否被经过。

观察到值域比较小,可以使用 vector 维护每一个点在哪些时刻被经过,查询的时候二分 \(l, r\) 即可。

vector<int> c[N];
bool calc(int l, int r, int t) {
    int lp = lower_bound(c[t].begin(), c[t].end(), l) - c[t].begin(), rp = upper_bound(c[t].begin(), c[t].end(), r) - c[t].begin() - 1;
    return lp <= rp;
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> q >> s;
    c[id({0, 0})].push_back(0);
    for(int i = 0, x = 0, y = 0; i < n; i ++) {
        if(s[i] == 'U') y ++;
        if(s[i] == 'D') y --;
        if(s[i] == 'L') x --;
        if(s[i] == 'R') x ++;
        p[i + 1] = {x, y};
        c[id({x, y})].push_back(i + 1);
    }
    for(int i = 1, x, y, l, r; i <= q; i ++) {
        cin >> x >> y >> l >> r;
        if(calc(0, l - 1, id({x, y})) || calc(r, n, id({x, y})) || calc(l, r - 1, id({p[l - 1].x + p[r].x - x, p[l - 1].y + p[r].y - y})))
            cout << "YES\n";
        else
            cout << "NO\n";
    }

    return 0;
}

E. Collapsing Strings

首先正难则反方便做,用总字符串长度减去被消掉的长度,观察到 \(C(a, b)\) 函数的本质是求 \(LCP(rev_a, b)\),\(rev_a\) 表示 \(a\) 的反转。

看到前缀考虑 Trie,插入所有字符串的反转,在插入的路径上增加 1 的贡献,意味着多匹配了一个字符,之后枚举 \(b\),在 Trie 上跑匹配,统计路径上所有的贡献。

最后需要 \(\times 2\),因为这样只会统计 \(b\) 作为第二个字符串的贡献。

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
// #define int long long
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
const int N = 1e6 + 10, M = 2e6 + 10;

int tr[M][26], cnt[M], idx;
void update(string s) {
    int u = 0;
    for(int i = (int)s.size() - 1; i >= 0; i --) {
        int c = s[i] - 'a';
        if(!tr[u][c]) tr[u][c] = ++ idx;
        u = tr[u][c]; 
        cnt[u] ++;
    }
}
int query(string s) {
    int u = 0, ans = 0;
    for(int i = 0; i < s.size(); i ++) {
        int c = s[i] - 'a';
        if(tr[u][c]) u = tr[u][c];
        else break;
        ans += cnt[u];
    }
    return ans;
}
int n;
string s[N];
signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> s[i], update(s[i]);
    long long ans = 0;
    for(int i = 1; i <= n; i ++) ans += s[i].size();
    ans = ans * 2 * n;
    for(int i = 1; i <= n; i ++)
        ans -= 2 * query(s[i]);
    cout << ans << '\n';

    return 0;
}

总结

B 一开始没看懂题,切慢了一点,不过亮点是把所有情况都讨论了一发过,C 交了两发罚时,以后注意一下特判的时候要保证所有的数据都读完了。

E 莽对了一发过,但是 D 观察到中点对称的性质之后没有想到怎么维护,看了 \(\text{\color{black}g\color{red}yh20}\) 大佬的代码之后恍然大悟。

标签:Educational,cout,159,题解,tr,cnt,long,++,int
From: https://www.cnblogs.com/MoyouSayuki/p/17876279.html

相关文章

  • CF1833G Ksyusha and Chinchilla 题解
    题意:思路:当$n\not\equiv0\space(mod\space3)$时,无解;当$n\equiv0\space(mod\space3)$时,设$size_u$表示以$u$为根的子树还剩余的节点个数,自根节点向叶子节点递归,返回时进行处理节点$u$:设节点$u$的子节点为长度为$len$的序列$v$,设......
  • [Educational Codeforces Round 159 (Rated for Div. 2)](https://codeforces.com/con
    EducationalCodeforcesRound159(RatedforDiv.2)好困,差点没打A-BinaryImbalance#include<bits/stdc++.h>#defineintlonglong#defineendl'\n'usingnamespacestd;voidsolve(){ strings; intn; cin>>n; cin>>s; if(n==......
  • [ARC120E] 1D Party 题解
    提供二分+DP做法。Solution题意给出\(n(\le2\times10^5)\)个单调递增偶整数\(a_i\),求最小的\(k\)满足每一个\(i\)都可以在\(k\)时刻之前(含)与相邻的数相遇。每个单位时间可以移动一个单位距离。思路启发式思考在想到正解之前,我们可以想想类正解。显然,在时间一单......
  • CF1695C Zero Path 题解
    题意:思路:设$minv$表示路径最小权值和,$maxv$表示路径最大权值和。当且仅当路径长度$n+m-2\equiv0\space(mod\space2)$且$minv\le0\lemaxv$时,一定有权值和为$0$的路径;否则,一定没有权值和为$0$的路径。证明:由于只能向右或向下走,路径长度......
  • CF1163B2 Cat Party (Hard Edition) 题解
    题意:思路:对于满足条件的区间$[1,x]$,有如下三种情况:$1$.所有元素出现次数都为$1$;$2$.除了一个元素出现次数为$1$之外,其余元素出现次数都相等;$3$.除了一个出现次数比其他数的出现次数多$1$的元素之外,其余元素出现次数都相等。在线处理:设$cnt_i......
  • CF1198B Welfare State 题解
    题意:有一个长度为$n$的序列$a$,给定$q$次操作,每次操作为以下两种之一:$1$.$1$$p$$x$:$a_p=x$$2$.$2$$x$:$a_i$$=$$max$$($$a_i$,$x$$)$$(1\lei\len)$求经过$q$次操作后的序列$a$。思路:$a_i$的最终值只受......
  • ABC331G 题解
    盒子里有\(n\)张\(m\)种卡片,第\(i\)种卡片有\(c_i\)张。\(\sumc_i=n\)。每次均匀随机选一张,再放回去。求拿出过的卡片包含全部种类所需要的取出次数的期望。对\(998244353\)取模。\(1\leqn,m\leq2e5,c_i\gt0\)。首先观察到,对于任意终止局面,最后取出的卡片一定......
  • Educational Codeforces Round 158 (Rated for Div. 2)
    EducationalCodeforcesRound158(RatedforDiv.2)AEDU的题总是感觉写起来怪怪的#include<bits/stdc++.h>#defineintlonglong#defineendl'\n'usingnamespacestd;inta[101];voidsolve(){intn,x;cin>>n>>x;intans=0;......
  • CF1442D Sum 题解
    题目链接点击打开链接题目解法\(n^3\)的\(dp\)是显然的但我们没用到\(a\)不降的性质考虑一个很妙的结论:最优选法中,至多只有一个序列取了且未取满为什么?如果最优情况下,存在选且未选满的序列为\(a,b\),第一个未选的元素为\(x,y\)如果\(a_x>a_{pre_y}\),那么选\(x\)......
  • 洛谷 P1044 [NOIP2003 普及组] 栈 题解
    洛谷P1044[NOIP2003普及组]栈题解Sol本题通过分析可得:假设现在进行\(12\)次操作,我们把push认为是在地图上向右走,pop向上走,那么其中一个合法的步骤可以是(\(p1\)代表push,\(p2\)代表pop):\(p1,p1,p2,p1,p2,p2,p1,p1,p2,p2,p1,p2\)。而且我们发现,他最终会......