【UNR #1】奇怪的线段树

SOL:

好像可以贪心啊,一颗树的左儿子的右儿子和右儿子的左儿子合并。其他递归处理。

#pragma GCC optimize("-Ofast")
#include<bits/stdc++.h>
using namespace std;
int n,lx,rx,mx,ux,ans;
int sol(int op,int l,int r,int &lx,int &rx,int &mx,int &ux) {
    int x; scanf("%d",&x);
    if (!op&&x) {puts("OwO");exit(0);}//it->fa=white && it=black is impossible
    if (l<r){
        int mid,ll,rr,l1,r1,l2,r2,m1,m2,u1,u2;
        scanf("%d",&mid);
        ll=sol(x,l,mid,l1,r1,m1,u1);
        rr=sol(x,mid+1,r,l2,r2,m2,u2);
        int mn=min(r1,l2); //it->son[0]->son[1] and it->son[1]->son[0] merge fisrt
        rx=r1-mn,lx=l2-mn; ans+=mn; ux=mn;
        if (!ll) {ans+=lx; lx=0; } // it->son[0] can‘t merge
        if (!rr) {ans+=rx; rx=0; }
        if (m1&&!l2) {
            if (u2) {u2--; ans--; ++lx; ++rx;}// as the father of seq so cancel the hypothesis
            else ++lx;
        }
        if (m2&&!r1) {
            if (u1) {u1--; ans--; ++lx; ++rx;}
            else ++rx;
        }
        if (!ll&&!rr) mx=x; else mx=0; //whether this seq can merge
        lx+=l1; rx+=r2;
        if (ll) ux+=u2; if (rr) ux+=u1; // ux‘s mean is the number of merged seq
    }  else {lx=rx=ux=0; mx=x;}
    return x;
}
signed main () {
//    freopen("u2.in","r",stdin);
    scanf("%d",&n);
    sol(1,1,n,lx,rx,mx,ux);
    printf("%d",ans+lx+rx+mx);
    return 0;
}

原文地址:https://www.cnblogs.com/rrsb/p/9335776.html

时间: 2024-10-16 14:19:47

【UNR #1】奇怪的线段树的相关文章

UOJ 217 奇怪的线段树

http://uoj.ac/problem/217 题意就不X了,思路在这: 居然一开始把sap里面的mn设置为inf了,我是傻逼.. #include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x3f3f3f3f int go[200005],first[200005],next[200005],fl

【vijos】1750 建房子(线段树套线段树+前缀和)

https://vijos.org/p/1750 是不是我想复杂了.... 自己yy了个二维线段树,然后愉快的敲打. 但是wa了两法.......sad 原因是在处理第二维的更新出现了个小问题,sad. void pushup1(int x) { for1(i, 1, mm<<2) mn[x][i]=min(mn[lc][i], mn[rc][i]); } 这里注意是mm*4...我该好好想想了..这是在dbg的时候找出来的问题.sad. 我觉得很奇怪,线段树的底层节点一共就mm个,那么整棵树

POJ2374 Fence Obstacle Course 【线段树】

题目链接 POJ2374 题解 题意: 给出\(n\)个平行于\(x\)轴的栅栏,求从一侧栅栏的某个位置出发,绕过所有栅栏到达另一侧\(x = 0\)位置的最短水平距离 往上说都是线段树优化dp 我写了一个奇怪的线段树过了,似乎并没有和dp沾边 因为每次都是从某个栅栏的端点出发,到达某个位置的值等于[所有这些可出发的端点已产生的代价 + 到达这个点的距离] 的最小值 就用线段树维护每个区间 \(lm[u]\)表示在这个区间内的端点到达左端点的最小代价 \(rm[u]\)表示到右端点的最小代价 然

BZOJ 3878 Ahoi2014 奇怪的计算器 线段树

题目大意:给定n个操作,每个操作有四种形式,操作之后若<L就变成L,>R就变成R,现在给定q个输入,求他们的输出 n,q<=10W 将这q个数建立线段树,四个操作都可以在线段树上完成 但是溢出怎么办呢? 容易发现若x<=y,那么操作过后x一定<=y 因为四个操作都是线性的,溢出也不会反转两个数的大小关系 那么我们可以预先将q个数排序 那么溢出的数一定是连续的两段 区间修改就行了 至于怎么找两端溢出的区间-- 每个节点维护一个区间最大值和最小值就好了 此外数据还是比较良心的 不

【BZOJ3878】【Ahoi2014】奇怪的计算器 维护区间性质。线段树

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44037685"); } 题解: 先排序然后插入线段树 用线段树每次对全区间进行操作. 然后维护哪些段区间溢出了,对这段区间进行赋值. 溢出处理: 一个区间的左端点大于最大值,或者右端点小于最小值 那么这个区间就该被覆盖. 覆盖,加特

uoj#388. 【UNR #3】配对树(线段树合并)

传送门 先考虑一个贪心,对于一条边来说,如果当前这个序列中在它的子树中的元素个数为奇数个,那么这条边就会被一组匹配经过,否则就不会 考虑反证法,如果在这条边两边的元素个数都是偶数,那么至少有两组匹配经过它,那么把这两条路径都删去这条边可以更优.如果两边是奇数,一定至少有一条路径经过它,去掉这组匹配之后就变成了偶数的情况.证毕 然后是一个神仙的转化,我们对于一颗子树中的元素,在序列里标记为\(1\),否则为\(0\),那么这条边出现次数就是序列中长度为偶数且区间和为奇数的区间个数 考虑用线段树合并

[luogu P3801] 红色的幻想乡 [线段树][树状数组]

题目背景 蕾米莉亚的红雾异变失败后,很不甘心. 题目描述 经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放. 我们将幻想乡看做是一个n*m的方格地区,一开始没有任何一个地区被红雾遮盖.蕾米莉亚每次站在某一个地区上,向东南西北四个方向各发出一条无限长的红雾,可以影响到整行/整列,但不会影响到她所站的那个地区.如果两阵红雾碰撞,则会因为密度过大而沉降消失.灵梦察觉到了这次异变,决定去解决它.但在解决之前,灵梦想要了解一片范围红雾的密度.可以简述为两种操

[BZOJ 1018][SHOI2008]堵塞的交通traffic(线段树)

Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵解决,道路才会恢复畅通.初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度 发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入

归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k大 ,,,, 这个问题的通用算法是 划分树,, 说白一点就是把快速排序的中间结果存起来, 举个栗子 原数列 4 1 8 2 6 9 5 3 7 sorted 1 2 3 4 5 6 7 8 9 ........................... qs[0] 4 1 8 2 6 9 5 3 7 q