传送门

题意:

  庭院中有 n 个围栏,每个围栏上都被涂上了不同的颜色(数字表示);

  有 m 条指令,每条指令给出一个整数 x ,你要做的就是将区间[ x第一次出现的位置 , x最后出现的位置 ]中的围栏

  全部涂成 x ,经过 m 次操作后,输出每个围栏的涂色情况;

题解:

  比赛的时,在读完题后,一瞬间,想到了线段树的区间更新,懒惰标记,but 我已经好久好久没写过线段树的代码了(嫌代码太长,逃);

  所以,比赛时,就不了了之,去看其他题了;

  今天,温习了一下线段树的用法,重新思考了本题的解题思路,感觉,线段树可以做出来;

  然后,对着电脑撸了一个线段树版的代码,一发AC,哈哈,开森~~~~~~

  手动艾特两个不相信线段树可以AC的童鞋,哈哈哈!

  

  具体思路:

  首先准备一个双端队列 q[ maxn ]; (maxn = 3e5+50 ,因为 ci ≤ 3*105

  q[ i ] 中存储的是所有的被涂上颜色 i 的栅栏编号,按顺序从小到大存储;

  对于每一个指令 x ,首先判断 q[x].size() 是否大于 1,如果大于 1,令 f = q[x].front() , e = q[x].end();

  然后,判断下标 f 和 e 对应的栅栏的颜色是否为 x ,如果是,通过线段树的区间更新+懒惰标记将区间[f,e]染成 x,接着执行下一条指令;

  如果 f 或 e 对应的栅栏颜色在之前被涂成了其他颜色,那么在 q[x] 中查找下一个满足条件的区间,如果找不到,不操作,执行下一条指令;

  最后,调用线段树的查询操作,输出答案。

AC代码:

 #include<iostream>
#include<cstdio>
#include<deque>
using namespace std;
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
const int maxn=3e5+; int n,m;
int a[maxn];
deque<int >q[maxn];
struct SegmentTree
{
int l,r;
int color;
int mid()
{
return l+((r-l)>>);
}
}segTree[*maxn]; void buildSegTree(int pos,int l,int r)
{
segTree[pos].l=l;
segTree[pos].r=r;
segTree[pos].color=;
if(l == r)
{
segTree[pos].color=a[l];
return ;
} int mid=l+((r-l)>>);
buildSegTree(ls(pos),l,mid);
buildSegTree(rs(pos),mid+,r);
} /**
向下更新,与区间更新懒惰标记不同的是
直接将pos的左右儿子的color赋值为x
*/
void pushDown(int pos)
{
int &x=segTree[pos].color;
if(x != )
{
segTree[ls(pos)].color=x;
segTree[rs(pos)].color=x;
x=;
}
}
/**
将区间[l,r]所包含的子区间的color值赋为x
出现的bug:起初直接将64行的赋值操作写成了
segTree[pos].color=a[l];
调试了好大会;
因为 a[l] 是改变前的涂色情况,如果l号栅栏在之前被染成了其他颜色
那么l号栅栏的颜色就不是a[l]了
*/
void Update(int pos,int l,int r,int x)
{
if(l <= segTree[pos].l && r >= segTree[pos].r)
{
segTree[pos].color=x;
return ;
}
pushDown(pos); int mid=segTree[pos].mid();
if(r <= mid)
Update(ls(pos),l,r,x);
else if(l > mid)
Update(rs(pos),l,r,x);
else
{
Update(ls(pos),l,mid,x);
Update(rs(pos),mid+,r,x);
}
}
int Query(int pos,int index)
{
if(segTree[pos].l == segTree[pos].r)
return segTree[pos].color; pushDown(pos); int mid=segTree[pos].mid();
if(index <= mid)
return Query(ls(pos),index);
else
return Query(rs(pos),index);
}
void Solve()
{
buildSegTree(,,n);
for(int i=;i <= m;++i)
{
int x;
scanf("%d",&x);
if(q[x].size() <= )
continue; /**
寻找可行的区间[f,e]
*/
int f=q[x].front();
int e=q[x].back();
while(Query(,f) != x && !q[x].empty())
{
q[x].pop_front();
if(!q[x].empty())
f=q[x].front();
}
while(Query(,e) != x && !q[x].empty())
{
q[x].pop_back();
if(!q[x].empty())
e=q[x].back();
}
//确保f != e
if(q[x].size() > )
Update(,f,e,x);
}
for(int i=;i <= n;++i)
printf("%d ",Query(,i));
printf("\n");
}
int main()
{
// freopen("C:/Users/hyacinthLJP/Desktop/stdin/contest","r",stdin);
scanf("%d",&n);
for(int i=;i <= n;++i)
{
scanf("%d",a+i);
q[a[i]].push_back(i);
}
scanf("%d",&m);
Solve(); return ;
}

Gym 101911E "Painting the Fence"(线段树区间更新+双端队列)的更多相关文章

  1. ZOJ 1610 Count the Color(线段树区间更新)

    描述Painting some colored segments on a line, some previously painted segments may be covered by some ...

  2. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

  3. hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...

  4. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  5. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  6. HDU 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

  7. POJ-2528 Mayor's posters (线段树区间更新+离散化)

    题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...

  8. ZOJ 1610 Count the Colors (线段树区间更新)

    题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...

  9. POJ 2528 Mayor's posters (线段树区间更新+离散化)

    题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...

随机推荐

  1. eclipse 启动问题Eclipse启动时报错:A Java RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No java virtual machine was found after searching the following locat

    从其他人直接复制的环境导致的问题. 正常双击出现当前异常,以管理员权限启动可以正常启动. ---------------------------Eclipse--------------------- ...

  2. hdu-2328(暴力枚举+kmp)

    题意:给你n个字符串,问你这n个串的最长公共子串 解题思路:暴力枚举任意一个字符串的所有子串,然后暴力匹配,和hdu1238差不多的思路吧,这里用string解决的: 代码: #include< ...

  3. GitHub大佬:供计算机学习鉴黄功能的图片数据库

    ps:学无止境 想要构建一套鉴黄系统,必须有大量的真实图片供计算机进行学习,以便于区分开正常图片和黄色图片. 近期有位加拿大程序员在Github上传了图片列表,里面包含了大量图片地址可以供计算机进行学 ...

  4. BZOJ1004[HNOI2008]Cards——polya定理+背包

    题目描述 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色 ...

  5. BZOJ4519[Cqoi2016]不同的最小割——最小割树+map

    题目描述 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成 两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割.对于带权图来说,将 所有顶点处在 ...

  6. robotframework基本语法一

    *** Settings *** Library OperatingSystem #Settings:导入测试库,资源文件,变量文件,为创建测试套件和test cases定义元数据 *** Varia ...

  7. 【XSY2751】Mythological IV 线性插值

    题目描述 已知\(f(x)\)为\(k\)次多项式. 给你\(f(0),f(1),\ldots,f(k)\),求 \[ \sum_{i=1}^nf(i)q^i \] \(k\leq 500000,n\ ...

  8. nginx 重定向 说明

    一.nginx 两个操作系统的安装见以前的随笔(已安装请跳过) linux上搭建nginx windows上搭建nginx 二.Nginx重定向——直接到项目,而非nginx欢迎页 默认ngin修改n ...

  9. 爬虫_豆瓣电影top250 (正则表达式)

    一样的套路,就是多线程还没弄 import requests import re import json headers = 'Mozilla/5.0 (Windows NT 10.0; WOW64) ...

  10. yyb省选前的一些计划

    突然意识到有一些题目的计划,才可以减少大量查水表或者找题目的时间. 所以我决定这样子处理. 按照这个链接慢慢做. 当然不可能只做省选题了. 需要适时候夹杂一些其他的题目. 比如\(agc/arc/cf ...