首页 > 其他分享 >ARC181题解(A-D)

ARC181题解(A-D)

时间:2024-08-04 23:49:58浏览次数:7  
标签:return ARC181 int 题解 ll cin long sum

A - Sort Left and Right

答案为 0 即已经排序。

考虑答案为 1 的情况:一定是存在一个 \(p\),使得 \(\min_{i=1}^{p}a_i=p\) 且 \(a_p=p\),这时只要选择 \(p\) 即可。

考虑答案为 2 的情况:如果 \(a_1\neq n\operatorname{or}a_n\neq 1\),一定可以通过先操作某个数,把 \(1\) 或者 \(n\) 放到正确的位置,然后进行答案为 1 的操作即可。共操作 2 次。

答案一定不超过 3:如果 \(a_1= n\operatorname{and}a_n=1\),这时无法通过某种操作直接变成答案为 1 的情况。

所以只能先随便操作一下,就可以变成答案为 2 的情况。共操作 3 次。

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

const int N = 2e5 + 5;
int n, a[N];

bool ok0()
{
    for(int i = 1; i <= n; i ++)
        if(a[i] != i) return 0;
    return 1;
}

bool ok1()
{
    int mx = 0;
    for(int i = 1; i <= n; i ++)
    {
        mx = max(mx, a[i]);
        if(i == a[i] && mx == a[i]) return 1;
    }
    return 0;
}

void solve()
{
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    if(ok0()) return cout << 0 << "\n", void();
    if(ok1()) return cout << 1 << "\n", void();
    cout << 2 + (a[1] == n && a[n] == 1) << "\n";
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int t;cin >> t;while(t --) solve();

    return 0;
}

B - Annoying String Problem

注意到如果 \(x\) 和 \(y\) 有公共前缀 \(pre\),那么可以同时去掉 \(pre\),答案不变。

不妨设现在的 \(x_0=\texttt{0},y_0=\texttt{1}\),并且 \(|S|<|T|\)。

因为 \(f(S,T,x)=f(S,T,y)\),所以可以把每个 \(1\) 拆成 \(01\),\(T=T'+S\),用 \(T'\) 替换 \(T\),然后消去相同前缀,这样答案仍然不变。

感性理解一下,\(S\) 和 \(T\) 存在相同子串 \(P\) 使得 \(S,T\) 都是一些 \(P\) 串在一起得到的。

于是可以设 \(S=aP,T=bP\)。可以通过解方程得到 \(a,b\)。

可以通过 \(x,y\) 列出方程:

\(\sum_{i=1}^{|x|}[x_i=0]a+\sum_{i=1}^{|x|}[x_i=1]b=\sum_{i=1}^{|y|}[y_i=0]a+\sum_{i=1}^{|y|}[y_i=1]b\)

然后移项解方程得出 \(a,b\) 关系,得出 \(k_1a=k_2b(\gcd(k_1,k_2)=1)\)。

于是有 \(\dfrac{a}{k_2}=\dfrac{b}{k_1}\)。因为 \(a\) 要是 \(k_2\) 倍数,于是只要判断是否存在 \(P\) 使得 \(S=k_2P\) 即可。

中间要特判未知数系数为负数,为 0 的情况。

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

bool ok(string s, int x)
{
    if(s.size() % x) return 0;
    int n = s.size(), d = n / x;
    for(int i = 0; i < n; i += d)
    {
        for(int j = 0, k = i; j < d; j ++, k ++)
            if(s[j] != s[k])
                return 0;
    }
    return 1;
}

void solve()
{
    string s; cin >> s;
    string s1, s2;
    cin >> s1 >> s2;
    int x = 0, y = 0;
    for(char c : s1) x += c == '0', y += c == '1';
    for(char c : s2) x -= c == '0', y -= c == '1';
    y = -y;
    if(y == 0)
    {
        if(x == 0) return cout << "Yes" << "\n", void();
        else return cout << "No\n", void();
    }
    if(x == 0) return cout << "Yes\n", void();
    if(1ll * x * y < 0) return cout << "No\n", void();
    if(x < 0) x = -x, y = -y;
    int d = __gcd(x, y);
    x /= d, y /= d;
    if(ok(s, y)) cout << "Yes\n";
    else cout << "No\n";
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int t;cin >> t;while(t --) solve();

    return 0;
}

C - Row and Column Order

令原题的 \(p,q\) 为下文的 \(a,b\)。

令下文的 \(p,q\) 为满足 \(p_{a_i}=i,q_{b_i}=i\) 的排列。

考虑一种思路:

优先满足 \(a\),尽量捎带上 \(b\)。

考虑对于每个点 \((i,j)\),填入 \([p_i>q_j]\)。

然后我们发现,这样会满足 \(a\),并且反着满足了 \(b\)。

所以令 \(q'_{b_i}=n-i+1\)。

对于每个点 \((i,j)\),填入 \([p_i>q'_j]\) 即可。

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

const int N = 505;

int n, a[N], b[N];
int p[N], q[N];

int ans[N][N];

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) cin >> b[i];
    for(int i = 1; i <= n; i ++) p[a[i]] = i;
    for(int i = 1; i <= n; i ++) q[b[i]] = n - i + 1;
    for(int i = 1; i <= n; i ++)
    for(int j = 1; j <= n; j ++)
        ans[i][j] = p[i] > q[j];
    for(int i = 1; i <= n; i ++, cout << "\n")
    for(int j = 1; j <= n; j ++)
        cout << ans[i][j];

    return 0;
}

D - Prefix Bubble Sort

考虑枚举每个数,考虑什么时候会让逆序对少 1。

观察性质,设 \(c_i=\sum_{j=1}^{i-1}[p_j>p_i]\)。

设 \(k_i\) 为最小的 \(d\) 使得 \(a_d\ge p_i\)。

我们发现,对于 \(p_i\),它会给从第 \(k_i\) 次开始的连续 \(c_i\) 次操作都贡献 -1 的逆序对数。

于是树状数组计算 \(c_i\),二分查找 \(k_i\),复杂度 \(O(n\log n)\)。

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

const int N = 2e5 + 5;

struct bit
{
    int a[N];
    int lbit(int x) {return x & -x;}
    void upd(int x, int v)
    {
        for(int i = x; i < N; i += lbit(i)) a[i] += v;
    }
    int qry(int x)
    {
        if(!x) return 0;
        int s = 0;
        for(int i = x; i; i -= lbit(i)) s += a[i];
        return s;
    }
} t;

int n, a[N], m, b[N];
int d[N];

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    cin >> m;
    for(int i = 1; i <= m; i ++) cin >> b[i];
    ll sum = 0;
    for(int i = 1; i <= n; i ++)
    {
        int p = i - 1 - t.qry(a[i]);
        sum += p;
        t.upd(a[i], 1);

        int l = lower_bound(b + 1, b + m + 1, i) - b;
        d[l] ++, d[min(m + 1, l + p)] --;
    }
    for(int i = 1; i <= m; i ++)
    {
        d[i] += d[i - 1];
        sum -= d[i];
        cout << sum  << "\n";
    }

    return 0;
}

还可以枚举二分的答案,这样可以少一半常数。

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

const int N = 2e5 + 5;

struct bit
{
    int a[N];
    int lbit(int x) {return x & -x;}
    void upd(int x, int v)
    {
        for(int i = x; i < N; i += lbit(i)) a[i] += v;
    }
    int qry(int x)
    {
        if(!x) return 0;
        int s = 0;
        for(int i = x; i; i -= lbit(i)) s += a[i];
        return s;
    }
} t;

int n, a[N], m, b[N];
int d[N];

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    cin >> m;
    for(int i = 1; i <= m; i ++) cin >> b[i];
    ll sum = 0;
    b[m + 1] = n;
    for(int i = 1; i <= m + 1; i ++)
    {
        for(int j = b[i - 1] + 1; j <= b[i]; j ++)
        {
            int p = j - 1 - t.qry(a[j]);
            sum += p;
            t.upd(a[j], 1);
            d[i] ++, d[min(m + 1, i + p)] --;
        }
    }
    for(int i = 1; i <= m; i ++)
    {
        d[i] += d[i - 1];
        sum -= d[i];
        cout << sum  << "\n";
    }

    return 0;
}

标签:return,ARC181,int,题解,ll,cin,long,sum
From: https://www.cnblogs.com/adam01/p/18342432

相关文章

  • Java环境变量配置的最佳实践和常见问题解决方案
    Java环境变量配置的最佳实践和常见问题解决方案大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java开发中,环境变量的配置是保证应用程序顺利运行的关键。无论是在本地开发环境还是生产环境,正确配置Java环境变量不仅能提升开发效率,还能避免许多常见......
  • Codeforces Round 891 (div.3) D题解析
    CodeForcesRound898(div4)D题.StrongVertices大致思路对于题目的给的式子,au-av>=bu-bv,我们可以通过移项得到au-bu>=av-bv,这样就能够构造出来一个ai-bi的项出来对于构造出来的项,我们可以遍历一遍用数组把每一个项存起来,找到值最大的项,值最大的项所对应的下标就是强顶......
  • 【秋招笔试】2024-08-03-科大讯飞秋招笔试题(算法岗)-三语言题解(CPP/Python/Java)
    ......
  • Luogu P1777 帮助 题解 [ 紫 ] [ 线性 dp ] [ 状压 dp ]
    帮助:大毒瘤!!!调了我2h,拍了我2h,最后没调出来,重写才AC。wdnmd。思路这题主要是线性dp,而状压dp只是最后在统计答案时的一个辅助。首先定义\(dp[i][j][k]\)为考虑前\(i\)本书,已经抽出来了\(j\)本,最后没被抽出来的一本书是高度\(k\)的最小混乱度。每次放入的书与最后一位......
  • Luogu P10842 Piggy and Trees 题解 [ 绿 ] [ 拆边 ] [ 贡献思维 ]
    PiggyandTrees:把路径拆成边的思维题。思路一看到这题的路径,就想到了LuoguP3177树上染色这题化路径为边的贡献,分别计算的思维。那么对于此题,先来观察题目里式子的意思:对于树上的每个无序点对,求出树上每个点到这些点对之间的最短路径的距离之和。枚举点对对应的就是前两......
  • 【面试题解答】一个有序数组 nums ,原地删除重复出现的元素
    面试题解答仅供学习文章目录面试题解答题目一、python代码1.1代码1.2示例用法1.2.1示例11.2.2示例2二、讲解2.1初始化2.2遍历2.3返回题目要解决这个问题,可以使用双指针方法进行原地修改,以确保每个元素最多出现两次。一、python代码1.1代码defr......
  • 2024梦熊BeiJing集训题目题解目录
    Day1基础动态规划luoguP1896[SCOI2005]互不侵犯codeforces1209ERotateColumns(easy)codeforces1209ERotateColumns(hard)杂题luoguP2371[国家集训队]墨墨的等式AtCoderabc219_fCleaningRobotP3043[USACO12JAN]BovineAllianceG[ARC105C]CamelsandB......
  • Leetcode 第 135 场双周赛题解
    Leetcode第135场双周赛题解Leetcode第135场双周赛题解题目1:3222.求出硬币游戏的赢家思路代码复杂度分析题目2:3223.操作后字符串的最短长度思路代码复杂度分析题目3:3224.使差值相等的最少数组改动次数思路代码复杂度分析题目4:思路代码复杂度分析Leetcode......
  • CodeForces-808#D 题解
    思路分析分析样例1:3132原数组被分成1和32两部分,将2移到左边即可。我们设左边部分的和为\(s1\),右边为\(s2\),可以发现对于任何分割方式,只有满足\(s1\pmx=s2\mpx\)才可以继续讨论答案是否成立。推论1:由于\(x\ina\)(\(a\)为题目所给数列),因此\(|\s1-s2......
  • 洛谷 统计天数 + 语句解析 题解
    题目:P1567统计天数P1597语句解析第一道:P1567统计天数题目描述炎热的夏日,KC非常的不爽。他宁可忍受北极的寒冷,也不愿忍受厦门的夏天。最近,他开始研究天气的变化。他希望用研究的结果预测未来的天气。经历千辛万苦,他收集了连续 N(1≤N≤10^6)天的最高气温数据。现在......