Problem G. Colors Overflow
Input file: standard input
Output file: standard output
Balloon Color: Dark Green
If there is one thing Ziad is good at, it’s creating new colors. In order to use his magical skill to its limit,
he decided to start a new career in painting. In order to do so he asked Joud to help him.
Joud presented Ziad with an infinite length line. Initially all points of the line are colorless. After examining
the line, Ziad noticed that it’s not an ordinary line. Even if a point is painted multiple times, it keeps all
the colors without mixing them, and when looking at it you can clearly see all the colors separated.
In order to test Ziad’s skills Joud presented him also with Q queries. Each query is of the type "t L R".
Queries can be of the following two types, depending on the value of t:
1. "1 L R"This is a task for Ziad to color each sub-segment of the range [L, R] inclusive, each with a
unique color that has never been used before. For example when asked to paint the range [3, 6] he will
paint segments [3 3], [3 4], [3 5], [3 6], [4 4], [4 5], [4 6], [5, 5], [5 6] and [6 6], each of them with a unique
color that has never been used before.
2. "2 L R"This query means Ziad has to look at the range [L, R] inclusive, and write down the number
of different colors that appear inside the range.
Anyways, Ziad is a little busy packing sugar and tea for his trip to be a judge, so he asked for your help
answering these queries.

Input

The first line contains a single integer T, denoting the number of test cases.

Each test case start with a line containing an integer Q (1 ≤ Q ≤ 105), denoting the number of queries.

The next line contains Q lines describe the queries. Each line has one query of the form "t L R"(1 ≤ t ≤ 2)

(1 ≤ L ≤ R ≤ 105).

Output

For each test case and for each query of the second type, print a single line, indicating the number of

unique colors in the range [L, R].

思路:

将每种颜色看成一条线段,则每次1操作相当于在区间内画了若干条线段,2操作相当于询问指定区间内线段数。

则对于每次询问,统计[1,L)的右端点数和[1-R]的左端点数,后者减前者,即得到答案(具体可画图理解),而每次1操作增加的左端点数为递减等差数列,增加的右操作数为与之倒序的递增等差数列。

参考了HH学长的实现思路,利用这个性质,用分块的思想来维护区间内左右端点数。

在实现上,对于全部询问Q,第一次,我们只更新右端点数,并在询问操作时把指定区间的右端点数减入到对应ans里;第二次,我们只更新左端点数,并在询问操作时把指定区间内左端点数加入到对应ans里。其中第一次完成后,将整个区间左右旋转,并初始化,使得不同但对称的操作,代码能够复用,很巧妙~~具体实现见代码

#include<iostream>
#include<algorithm>
#define de(x) cout<< #x <<" = "<<x<<endl
using namespace std;
typedef long long ll;
const int bsz=350,N=1e5+7,n=1e5+2;
int bn,bl[N],br[N],sz[N];
int qop[N],ql[N],qr[N];
ll ans[N],bs[N],bb[N],bd[N],a[N];
void init(int n)
{
bn=(n-1)/bsz+1;
for (int i=0;i<bn;++i)
{
bl[i]=i*bsz;
br[i]=min(n,(i+1)*bsz);
sz[i]=br[i]-bl[i];
bs[i]=bd[i]=bb[i]=0;
}
for (int i=0;i<n;++i)
a[i]=0;
}
void build(int b)
{
for (int i=bl[b];i<br[b];++i)
a[i]+=bb[b]+(i-bl[b]+1)*bd[b];
bb[b]=bd[b]=0;
}
void update(int b,int l,int r)
{
int nl=max(l,bl[b]),nr=min(br[b],r);
if (nl>=nr)
return;
if (nr-nl==sz[b])
{
bb[b]+=nl-l; //维护这一块的基数
bd[b]++; //维护这一块的公差
bs[b]+=(1+sz[b])*sz[b]/2+(nl-l)*sz[b]; //用求和公式维护这一块端点数
return;
}
for (int i=nl;i<nr;++i) //如果该块没有被包含,则直接暴力维护
{
bs[b]+=i-l+1;
a[i]+=i-l+1;
}
return;
}
ll query(int b,int l,int r)
{
int nl=max(l,bl[b]),nr=min(br[b],r);
if (nl>=nr)
return 0;
if (nr-nl==sz[b]) //被包含直接返回这一块的值
return bs[b];
//没有被包含时
ll res=0;
build(b);//通过之前维护的公差和基数暴力统计端点数
for (int i=nl;i<nr;++i)
res+=a[i];
return res;
}
int main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin>>T;
while (T--)
{
int q;
cin>>q;
fill_n(ans,q,0);
for (int i=0;i<q;++i)
{
cin>>qop[i]>>ql[i]>>qr[i];
--ql[i];
--qr[i];
}
init(n);
for (int i=0;i<q;++i)
{
if (qop[i]==1)
for (int j=0;j<bn;++j)
update(j,ql[i],qr[i]+1);
else
for (int j=0;j<bn;++j)
ans[i]-=query(j,0,ql[i]);
//旋转
ql[i]=n-1-ql[i];
qr[i]=n-1-qr[i];
swap(ql[i],qr[i]);
}
init(n);
for (int i=0;i<q;++i)
{
if (qop[i]==1)
for (int j=0;j<bn;++j)
update(j,ql[i],qr[i]+1);
else
{
for (int j=0;j<bn;++j)
ans[i]+=query(j,ql[i],n);
cout<<ans[i]<<endl;
}
}
}
return 0;
}

Tishreen-CPC 2018 G. Colors Overflow(分块)的更多相关文章

  1. 2018北京网络赛 G The Mole /// 分块暴力 点线距离

    题目大意: 给定n段线段 编号为1~n 接下来m个询问 给定一点 输出离该点最近的线段的最小编号(距离相等时取编号小的) 题解 大致就是 1.坐标范围为(0,2^16-1) 将坐标系划分为2^8*2^ ...

  2. LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)

    题面 LOJ #2802. 「CCC 2018」平衡树 题面有点难看...请认真阅读理解题意. 转化后就是,给你一个数 \(N\) ,每次选择一个 \(k \in [2, N]\) 将 \(N\) 变 ...

  3. 【UOJ#435】【集训队作业2018】Simple Tree 分块+树链剖分

    题目大意: 有一棵有根树,根为 1 ,点有点权.现在有 m 次操作,操作有 3 种:1 x y w ,将 x 到 y 的路径上的点点权加上 w (其中 w=±1w=±1 ):2 x y ,询问在 x ...

  4. [Avito Code Challenge 2018 G] Magic multisets(线段树)

    题目链接:http://codeforces.com/contest/981/problem/G 题目大意: 有n个初始为空的‘魔法’可重集,向一个‘可重集’加入元素时,若该元素未出现过,则将其加入: ...

  5. Asia Yokohama Regional Contest 2018 G题 What Goes Up Must Come Down

    链接 G题 https://codeforces.com/gym/102082 使其成为单峰序列需要交换多少次相邻的数. 树状数组维护逆序对. 对于每个序列中的数,要么在单峰的左侧,要么在单峰的右侧, ...

  6. 2018 Arab Collegiate Programming Contest (ACPC 2018) G. Greatest Chicken Dish (线段树+GCD)

    题目链接:https://codeforces.com/gym/101991/problem/G 题意:给出 n 个数,q 次询问区间[ li,ri ]之间有多少个 GCD = di 的连续子区间. ...

  7. #6499. 「雅礼集训 2018 Day2」颜色 [分块,倍增,bitset]

    bitset压位,因为是颜色数,直接倍增,重合部分不管,没了. // powered by c++11 // by Isaunoya #include <bits/stdc++.h> #d ...

  8. ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syria, Lattakia, Tishreen University, April, 30, 2018

    ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syr ...

  9. kindeditor之video插件开发

    KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得编辑效果.不仅结构小巧,而且功能强大,最主要的是它采用插件的开发管理方式,能很容易再它的基础上添加插件来实现自 ...

随机推荐

  1. O057、Delete Volume 操作

    参考https://www.cnblogs.com/CloudMan6/p/5648665.html   状态为Available 的volume 才能够被delete,如果volume当前已经被at ...

  2. 关于mysql installer 的安装和环境变量配置

    MySQL针对不同的用户提供了2中不同的版本: MySQL Community Server:社区版.由MySQL开源社区开发者和爱好者提供技术支持,对开发者开放源代码并提供免费下载. MySQL E ...

  3. Flutter-动画-概念篇

    一.Flutter中的动画的基本概念图 二.Flutter各动画的概念 视图动画 补间动画 就是一个View,定义了起点和终点.时间以及运动曲线,并按照所定规则由起点运动到终点的过程. 帧动画 帧动画 ...

  4. java_day04_数组

    chap04目标:数组---------------------------------------------- 1.概述 数组是一组数据的集合,数组中的每个数据被称为元素.在java中,数组也是对 ...

  5. XML基础综合案例【三】

    实现简单的学生管理系统 使用xml当做数据,存储学生信息 ** 创建一个xml文件,写一些学生信息 ** 增加操作1.创建解析器2.得到document 3.获取到根节点4.在根节点上面创建stu标签 ...

  6. 用Nginx为多个http/socks代理做负载均衡(反向代理)

    近日遇到一个需求,某机器上在四个端口上开了四个http代理,因为每个代理都有流量限额,所以要平均着使用,但由使用者手动更改端口号又太麻烦,所以需要将这4个端口融合为1个,想到的办法就是用Nginx做负 ...

  7. STM32 stm32fxxx_flash.icf文件的作用详解

    文章转载自:https://blog.csdn.net/weibo1230123/article/details/80142210 每个芯片开发商都会针对每款芯片来编写一个.icf文件就是传说中的链接 ...

  8. Python tuple元组学习

    1.tuple和list非常类似,但是tuple一旦初始化就不能修改 classmates = ('Michael', 'Bob', 'Tracy') 现在,classmates这个tuple不能变了 ...

  9. 认识并初步应用GitHub——C++

    好好学习,天天向上 一.这是一个根据规定的开头 GIT的地址 https://github.com/Notexcellent GIT的用户名 Notexcxllent 学号后五位 82405 博客地址 ...

  10. 转 shell中的多进程【并发】

    原文地址https://bbs.51cto.com/thread-1104907-1-1.html 根据我个人的理解, 所谓的多进程 只不过是将多个任务放到后台执行而已,很多人都用到过,所以现在讲的主 ...