首页 > 其他分享 >[题解]CF1741D Masha and a Beautiful Tree

[题解]CF1741D Masha and a Beautiful Tree

时间:2024-06-24 12:32:23浏览次数:22  
标签:Beautiful int 题解 Tree 升序 最小值 区间 我们

思路

我们可以观察样例,不难发现:对于任意一段长度为 \(2^k\) 的区间中,如果最大值减最小值加 \(1\) 等于此区间的长度,那么一定有解。

因为,我们的目标是使整个序列升序排列。因此,我们在一个区间内的最大值减最小值加 \(1\) 与区间长度是相等的。

所以,我们可以用上述结论为判断无解的标准。

那么,如果我们有解,那么我们的交换次数又是多少呢?

结果为任意两个相对的左右子树中,左子树的最小值大于了右子树的最小值的数量。

因为,我们要使序列升序,那么左区间的最小值一定是要小于右区间的最小值的。

所以,我们在上述条件是成立的。

得出了这两个结论后,不难发现:我们一切的过程都与区间最值有关。那么,我们考虑建一棵线段树,维护区间最值。

然后依据上述条件进行操作即可。

Code

#include <bits/stdc++.h>  
#define re register  
  
using namespace std;  
  
const int N = 3e5 + 10;  
int T,n;  
int arr[N];  
  
struct node{  
    int l;  
    int r;  
    int Min;  
    int Max;  
}tr[N << 1];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + c - 48;  
        c = getchar();  
    }  
    return r * w;  
}  
  
inline void pushup(int u){  
    tr[u].Min = min(tr[u << 1].Min,tr[u << 1 | 1].Min);  
    tr[u].Max = max(tr[u << 1].Max,tr[u << 1 | 1].Max);  
}  
  
inline void build(int u,int l,int r){//建树模板   
    tr[u] = {l,r};  
    if (l == r){  
        tr[u].Max = tr[u].Min = arr[l];  
        return;  
    }  
    int mid = l + r >> 1;  
    build(u << 1,l,mid);  
    build(u << 1 | 1,mid + 1,r);  
    pushup(u);  
}  
  
inline bool query1(int u,int l,int r){//按照刚才的规则判断是否合法   
    if (l == r) return true;  
    int mid = tr[u].l + tr[u].r >> 1;  
    if (!query1(u << 1,l,mid) || !query1(u << 1 | 1,mid + 1,r)) return false;//左右子树均为合法才行   
    if (tr[u].r - tr[u].l == tr[u].Max - tr[u].Min) return true;//还要判断本身是否合法   
    return false;  
}  
  
inline int query2(int u,int l,int r){//然后统计一下左子树最小值大于右子树最小值的数量   
    if (l == r) return 0;  
    int mid = tr[u].l + tr[u].r >> 1;  
    int res = query2(u << 1,l,mid) + query2(u << 1 | 1,mid + 1,r) + (tr[u << 1].Min > tr[u << 1 | 1].Min);//ans = 左子树的数量 + 右子树的数量 + 本身的数量   
    return res;  
}  
  
int main(){  
    T = read();  
    while (T--){  
        n = read();  
        for (re int i = 1;i <= n;i++) arr[i] = read();  
        build(1,1,n);  
        if (!query1(1,1,n)) puts("-1");  
        else printf("%d\n",query2(1,1,n));  
    }  
    return 0;  
}  

标签:Beautiful,int,题解,Tree,升序,最小值,区间,我们
From: https://www.cnblogs.com/WaterSun/p/18264807

相关文章

  • [题解]CF1741B Funny Permutation
    思路简单构造题,我们可以分为三种情况进行构造。\(n=3\)时,一定无解,输出-1。(你可以试试)\(n\bmod2=1\wedgen\neq3\)时,我们直接先输出\(n,n-1\),然后顺序输出即可。证明:令\(a\)为最后构造出的序列。那么,\(a_1=n,a_2=n-1,a_i=i-2(3\leqi\leq......
  • [题解]CF1732C2 Sheikh (Hard Version)
    思路首先证明一下当序列扩大时答案一定不劣。考虑\(f(l,r)\)到\(f(l,r+1)\)的变化。\[\begin{aligned}f(l,r)-f(l,r+1)&=s_{l,r}-xs_{l,r}-s_{l,r+1}+xs_{l,r+1}\\&=xs_{l,r+1}-xs_{l,r}-a_{r+1}\\&......
  • fdisk时WARNING: Re-reading the partition table failed with error 16: 设备或资源
    WARNING:Re-readingthepartitiontablefailedwitherror16:设备或资源现象:划分磁盘有警告, WARNING:Re-readingthepartitiontablefailedwitherror16:设备或资源忙.Thekernelstillusestheoldtable.Thenewtablewillbeusedatthenextrebootoraft......
  • WPF TreeView 三层绑定模板
    在WPF应用程序中,使用TreeView来展示三层数据结构是一个常见的需求。为此,你需要定义适当的数据绑定和模板。以下是一个完整的示例代码,展示如何实现这一点。数据模型首先,我们需要定义三层数据模型。假设我们有三层数据结构:RootItem包含ChildItem,ChildItem又包含SubChildItem。pub......
  • P3974 [TJOI2015] 组合数学 题解
    Description给一个网格图,其中某些格子有一些财宝。每次从左上角出发,只能往右或下走,每一次经过一个格子至多只能捡走一块财宝,至少要走几次才可能把财宝全捡完?\(1\leqn\leq1000\),\(1\leqm\leq1000\),每个格子中的财宝不超过\(10^6\)块。Solution考虑把每个点\((i,j)\)......
  • [题解]CF1066E Binary Numbers AND Sum
    思路考虑对于每一个\(a\)上数位进行分析。令\(a_i\)表示\(a\)在二进制表示中从左往右数的第\(i\)位上的数字,\(b_i\)同理。分类讨论一下\(a_i\)的取值对于答案的贡献:如果\(a_i=0\),对于这一位无论如何都不会拥有贡献。如果\(a_i=1\),因为\(b\)会向右移,所以能......
  • [题解]CF1061C Multiplicity
    题意给定一个长度为\(n\)的序列\(\{a_1,a_2,\dots,a_n\}\)。现在要在\(a\)选出非空子序列\(\{b_1,b_2,\dots,b_m\}\),使得所有的\(i\in[1,m]\),都有\(b_i\bmodi=0\)。求能够选取\(b\)序列的方案数模\(10^9+7\)的值。思路定义\(dp_{i,j}\)表示在\(\{a_1,a......
  • [题解]P2042 [NOI2005] 维护数列 - Splay解法
    P2042[NOI2005]维护数列一道思路不难,但实现细节很多的平衡树题,调了一天半终于做出来了w。对于初始序列,我们可以直接构建一条链(毕竟一个一个调用插入函数也可能形成一条链)。题解有递归直接构建成一棵严格平衡的二叉树的,这样也可以,常数可能会小一点。其中区间反转就是裸的文艺......
  • [MdOI R5] Many Minimizations & [ARC164F] Many Increasing Problems 题解
    讲下一个思路比较自然的基于自然数幂和的\(O(n\logn)\)且复杂度与\(m\)几乎无关的做法。不难发现让我们计数的问题是保序回归\(L_1\)中一条链的情况。这个情况有一个简单的slope-trick做法:用堆维护斜率,每次push进去两个当前的数,然后pop出一个最大值。最终所有数的和......
  • [MdOI R5] Many Minimizations & [ARC164F] Many Increasing Problems 题解
    讲下一个思路比较自然的基于自然数幂和的\(O(n\logn)\)且复杂度与\(m\)几乎无关的做法。不难发现让我们计数的问题是保序回归\(L_1\)中一条链的情况。这个情况有一个简单的slope-trick做法:用堆维护斜率,每次push进去两个当前的数,然后pop出一个最大值。最终所有数的和......