首页 > 其他分享 >洛谷P11183 [ROIR 2018 Day2] 大数据处理

洛谷P11183 [ROIR 2018 Day2] 大数据处理

时间:2024-11-14 13:07:21浏览次数:1  
标签:洛谷 交集 Day2 pos ROIR rch ans 节点 lch

涉及知识点:动态开点线段树,贪心

前言

很妙很感性直观的贪心,做完神清气爽。

题意

Link

有一个长为 \(2^k\) 的序列,编号从 \(0\) 开始,你要在上面染色,每次只能染色 \([k2^i,(k+1)2^i-1]\) 的区间(\(0\leq i<k\)),问最少要染色多少次才能变成给定的目标序列。目标序列以形如 \((x_1,y_1),(x_2,y_2),\dots,(x_n,y_n)\) 的格式给出,表示从 \(0\) 开始有长为 \(x_1\) 的颜色为 \(y_1\) 的段,然后长为 \(x_2\) 颜色为 \(y_2\) 的段,以此类推。

\(k\leq 30,n\leq 10^5\)。

思路

不难发现合法的染色区间其实就是原序列建出的线段树上的某个节点,于是问题转化为了在线段树上选一些点染色,每个叶子节点的颜色为距离它最近的被染色节点的颜色。为什么是距离最近的?因为我们肯定是先染长的段再染短的段最优(否则,先染短的就可能被后染的长的覆盖),对应线段树上就是先染浅的节点再染深的节点。

于是我们对目标序列建出一颗线段树,但是本题的空间肯定不允许我们建完整的线段树,可以考虑动态开点,假设当前节点对应的区间都是同一种颜色,就可以停止继续往下建了。这样建树在 update 一次时最多涉及 \(\log_2(2^k)=k\) 个节点,因此时空复杂度均为 \(O(nk)\)。

注意:这样建出的线段树仍然满足普通线段树“要么没有儿子,要么有两个儿子”的性质,不存在只有左儿子或右儿子的情况。

接下来就在线段树上贪心,我们给每个节点开一个集合,意为“该节点所代表区间在最优策略下,如果被染色,那么可能染成的颜色”。首先叶子节点的集合肯定就只有它自己的颜色,\(ans=1\)。而对于非叶子节点,我们取它左右儿子的交集,如果这个交集不为空,我们就可以在这些颜色当中选一个作为当前区间的颜色,因此当前节点的集合为这个交集,且 \(ans\) 为 \(ans_{lch}+ans_{rch}-1\);如果交集为空,那么当前节点为左右儿子并集,且 \(ans\) 为 \(ans_{lch}+ans_{rch}\)。

这是什么意思呢?当左右孩子中有交集时,说明左右孩子都存在某个区间染的颜色相同,因此直接在当前节点染而不是在左右孩子分别染,可以节省一次操作,由于在此处染色会“阻断”更上方的染色,因此交集外的颜色不用再被考虑。如果没有交集,那么该节点染成什么也不会更优,打包取并集交给更上方的节点处理。

还有一个问题,所谓这样的“阻断”会使得贪心错误吗?实际上是不会的,假设某处本应该取交集但取了并集,导致祖先某处应该取并集却取了交集,相当于为了一个小段,去染色了一个本该是其他颜色的大段,这一定是不优的。

例:

可自行尝试将上图黄圈所示部分本来取交集为(蓝)改为取并集(红+蓝),答案变劣。

代码

这里介绍一下 STL 的科技 set_intersectionset_union,当然还有个 set_difference,但此处没用到。

set_intersection(a.begin(),a.end(),b.end(),b.end(),inserter(c,c.begin())) 表示求 ab 的交集存放到 c 中,其他两个同理。而且其时间复杂度为线性的,太伟大了 STL

#define getmid int mid=(l+r)/2
int K,n,m,full;
struct Node{
    Node *lch,*rch;
    int t,ans;
    set<int>s;
    Node(){
        lch=rch=nullptr;
        t=-1;
        ans=0;
    }
};
Node* rt=nullptr;
void update(Node* &pos,int l,int r,int ll,int rr,int col){
    if(pos==nullptr) pos=new Node;
    if(ll<=l && r<=rr){
        pos->t=col;
        return;
    }
    getmid;
    if(ll<=mid) update(pos->lch,l,mid,ll,rr,col);
    if(mid<rr) update(pos->rch,mid+1,r,ll,rr,col);
}
void solve(Node* pos){
    if(pos->lch==nullptr){
        assert(pos->rch==nullptr);
        pos->s.insert(pos->t);
        pos->ans=1;
        return;
    }
    else{
        solve(pos->lch);solve(pos->rch);
        pos->ans=pos->lch->ans+pos->rch->ans;
        set_intersection(pos->lch->s.begin(),pos->lch->s.end(),
                         pos->rch->s.begin(),pos->rch->s.end(),
                         inserter(pos->s,pos->s.begin()));
        if(!pos->s.empty()){
            pos->ans--;
            return;
        }
        pos->s.clear();
        set_union(pos->lch->s.begin(),pos->lch->s.end(),
                  pos->rch->s.begin(),pos->rch->s.end(),
                  inserter(pos->s,pos->s.begin()));
    }
}
int main(){
    rd(K);rd(n);rd(m);
    full=(1<<K)-1;
    for(int i=1,x,y,l=0;i<=n;i++){
        rd(x);rd(y);
        update(rt,0,full,l,l+x-1,y);
        l+=x;
    }
    assert(rt);
    solve(rt);
    wt(rt->ans);
    return 0;
}

标签:洛谷,交集,Day2,pos,ROIR,rch,ans,节点,lch
From: https://www.cnblogs.com/SkyNet-PKN/p/18545774

相关文章

  • 【题解】洛谷P1712: [NOI2016] 区间
    P1712[NOI2016]区间我对尺取法并不敏感,所以感觉有点难度,我们想到按照区间长度排序加入使得满足单调性,直到有一个区间的覆盖次数达到了m就可以计算了,而这个就是尺取法,单调性使得我们答案总是最优的。覆盖次数就可以用线段树做,而且数据范围很大需要离散化,计算答案时注意把答案带......
  • 旺仔水饺-冲刺日志 Day2
    作业所属课程https://edu.cnblogs.com/campus/fzu/SE2024作业要求https://edu.cnblogs.com/campus/fzu/SE2024/homework/13305团队名称旺仔水饺102201140黎曼102201138黄俊瑶102201127罗永辉102201130郑哲浩102202144傅钰102202147赖越1722090......
  • 洛谷P1182 数列分段 Section II
    洛谷P1182数列分段SectionIIP1182数列分段SectionII数列分段SectionII题目描述对于给定的一个长度为的正整数数列,现要将其分成()段,并要求每段连续,且每段和的最大值最小。关于最大值最小:例如一数列要分成段。将其如下分段:第一段和为,第段和为,第段和为,和......
  • 洛谷P11228的C++题解
    题目分析题目题目让我们算出机器人走步后经过了多少个不重复的点这道题不是搜索!直接按照题意模拟就行了。遇到墙就向右转,不是就直行。特别注意:向右转也是一步!一个格子最多算一遍!我们可以用一个标记数组 st,走过的点就打上标记。判断走道的点有没有打上标记,有就不......
  • 洛谷题单 算法2-2 常见优化技巧
    洛谷题单算法2-2常见优化技巧单调栈单调栈最经典的应用,就是在一个数列里寻找距离元素最近的比其大/小的元素位置。模板题,寻找每个元素右边第一个比它大的元素下标。stack<int>s;for(inti=n;i>=1;i--){while(s.size()&&a[s.top()]<=a[i])s.pop();f[i]=s.......
  • Day2
    Day2当天站立式会议照片学生团队姓名学号昨天已完成的工作今天计划完成的工作工作中遇到的困难林涛(组长)3122004618完成登录模块开发修改管理员apinull杨森3122004629后台文件上传开发完成接收文件并保存如何保存的图片钟礼骏3122006504查询家长感......
  • 团队项目Scrum冲刺-day2
    一、每天举行站立式会议站立式会议照片一张昨天已完成的工作成员任务陈国金用户模块的部分接口开发凌枫登录页面陈卓恒管理题目页面的部分代码谭立业题目搜索页面的部分代码廖俊龙接口测试曾平凡前端页面测试曾俊涛题目模块的部分接口开发......
  • 洛谷P1784.数独
    P1784数独思路这个题目最麻烦的是如何判断我们需要判断每一行,每一列,每一个九宫格这里有个小技巧,把每一行,每一列,每一个九宫格哪个数有没有被用过用数组存起来哪个数字属于哪个九宫格也可以先先存起来intid[10][10]={{0,0,0,0,0,0,0,0,0,0},{0,1,1,1,2,......
  • 洛谷题单指南-二叉堆与树状数组-P1878 舞蹈课
    原题链接:https://www.luogu.com.cn/problem/P1878题意解读:n个男女排列一行,每人舞蹈技术是ai,每次找到相邻男女舞蹈技术差值绝对值最小的一对出列,输出每对出列的人员编号。解题思路:设初始有8人编号为:12345678将12,23,34,45,56,67,78中是男女的配对编号以及a......
  • 洛谷P3654
    P3654FirstStep(ファーストステップ)-洛谷|计算机科学教育新生态FirstStep(ファーストステップ)题目背景我们Aqours,要第一次举办演唱会啦!虽然学生会长看上去不怎么支持我们的样子,可是有了理事长的支持,我们还是被允许在校内的篮球场里歌唱!歌曲也好好地准备过了,名......