http://codeforces.com/problemset/problem/351/D

题意:

n个数的一个序列,m个操作

给出操作区间[l,r],

首先可以删除下标为等差数列且数值相等的一些数

然后可以对区间剩余数重排

继续删除下标为等差数列且数值相等的一些数

继续对区间进行重排

直至区间内没有数

问每次操作的最少删除次数

因为每次删除后可以重排

那么完全可以在第一次删除后就把区间相等的数排在一起

这样相等的数的下标就分别构成了公差为1的等差数列

所以问题转化为

设区间[l,r]内数有x种,

若在区间内有一种数,他的位置下标构成等差数列,输出x

否则,输出x+1

本题可以离线操作

区间内数的种类,用莫队算法很容易做

所以问题只剩下如何用莫队算法维护区间内 相同的数的下标构成等差序列 的数的种数

思路:

加一个数:

如果这个数在区间里没有出现过,等差序列数+1

否则,若加的数破坏了原有的一个等差序列,等差序列数-1

删一个数:

如果这个数在区间里只剩下1个,等差序列数-1

否则,若删的数使原来不能构成 等差序列的数构成了等差序列,等差序列数+1

每次操作的答案=区间数的种数+ k

若等差序列数=0,则k=1,否则k=0

具体实现:

预处理fl[i],fr[i]表示第i个数左/右第一个 相等但下标不能构成等差序列的位置

为了得到这个,还需要两个数组:

pre[i]  i左边第一个和i相等的数的位置

bac[i] i右边第一个和i相等的数的位置

若pre[pre[i]]-pre[i]==i-pre[i] 或者 pre[i]==0 fl[i]=fl[pre[i]](两个数一定是等差数列)

否则 fl[i]=pre[pre[i]]

fr同理

设莫队维护的当前区间为[L,R]

破坏等差数列:

若此时L正在递减,那就是fr[bac[i]]>R && fr[i]<=R

若此时R正在递增,那就是fl[pre[i]]<L && fl[i]>=L

产生等差数列:

若此时L正在递增,那就是fr[i]<=R && fr[bac[i]]>R

若此时R正在递减,那就是fl[i]>=L && fl[pre[i]]<L

#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 100002 int val[N],last[N];
int pre[N],fl[N];
int bac[N],fr[N]; struct node
{
int l,r;
int id;
}e[N]; int bl[N]; int sum[N]; int ans[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} bool cmp(node p,node q)
{
if(bl[p.l]!=bl[q.l]) return bl[p.l]<bl[q.l];
return p.r<q.r;
} int main()
{
int n;
read(n);
int x,y;
for(int i=;i<=n;++i)
{
read(val[i]);
pre[i]=last[val[i]];
last[val[i]]=i;
if(pre[pre[i]]-pre[i]==pre[i]-i || !pre[i]) fl[i]=fl[pre[i]];
else fl[i]=pre[pre[i]];
}
for(int i=;i<=n;++i) last[i]=n+;
fr[n+]=n+;
for(int i=n;i;--i)
{
bac[i]=last[val[i]];
last[val[i]]=i;
if(bac[bac[i]]-bac[i]==bac[i]-i || bac[i]==n+) fr[i]=fr[bac[i]];
else fr[i]=bac[bac[i]];
}
int m;
read(m);
for(int i=;i<=m;++i)
{
read(e[i].l);
read(e[i].r);
e[i].id=i;
}
int siz=sqrt(n);
for(int i=;i<=n;++i) bl[i]=(i-)/siz+;
sort(e+,e+m+,cmp);
int L=,R=,tmp=,dengcha=;
for(int j=;j<=m;++j)
{
x=e[j].l; y=e[j].r; for(int i=L-;i>=x;--i)
{
if(!sum[val[i]])
{
dengcha++;
tmp++;
}
else
{
if(fr[i]<=R && fr[bac[i]]>R) dengcha--;
}
sum[val[i]]++;
}
for(int i=L;i<x;++i)
{
if(sum[val[i]]==)
{
dengcha--;
tmp--;
}
else
{
if(fr[i]<=R && fr[bac[i]]>R) dengcha++;
}
sum[val[i]]--;
}
for(int i=R;i>y;--i)
{
if(sum[val[i]]==)
{
dengcha--;
tmp--;
}
else
{
if(fl[i]>=x && fl[pre[i]]<x) dengcha++;
}
sum[val[i]]--;
}
for(int i=R+;i<=y;++i)
{
if(!sum[val[i]])
{
dengcha++;
tmp++;
}
else
{
if(fl[i]>=x && fl[pre[i]]<x) dengcha--;
}
sum[val[i]]++;
}
L=x; R=y;
ans[e[j].id]=tmp+;
if(dengcha>) ans[e[j].id]--;
}
for(int i=;i<=m;++i) cout<<ans[i]<<'\n';
}
D. Jeff and Removing Periods
time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Cosider a sequence, consisting of n integers: a1, a2, ..., an. Jeff can perform the following operation on sequence a:

  • take three integers vtk (1 ≤ v, t ≤ n; 0 ≤ kv + tk ≤ n), such that av = av + tav + t = av + 2t, ..., av + t(k - 1) = av + tk;
  • remove elements avav + t, ..., av + t·k from the sequence a, the remaining elements should be reindexed a1, a2, ..., an - k - 1.
  • permute in some order the remaining elements of sequence a.

A beauty of a sequence a is the minimum number of operations that is needed to delete all elements from sequence a.

Jeff's written down a sequence of m integers b1, b2, ..., bm. Now he wants to ask q questions. Each question can be described with two integers li, ri. The answer to the question is the beauty of sequence blibli + 1, ..., bri. You are given the sequence b and all questions. Help Jeff, answer all his questions.

Input

The first line contains integer m (1 ≤ m ≤ 105). The next line contains m integers b1, b2, ..., bm (1 ≤ bi ≤ 105).

The third line contains integer q (1 ≤ q ≤ 105) — the number of questions. The next q lines contain pairs of integers, i-th of them contains a pair of integers liri (1 ≤ li ≤ ri ≤ m) — the description of i-th question.

Output

In q lines print the answers to Jeff's queries. Print the answers according to the order of questions in input.

Examples
input
5
2 2 1 1 2
5
1 5
1 1
2 2
1 3
2 3
output
2
1
1
2
2
input
10
2 1 3 3 3 3 1 3 1 1
10
4 8
2 10
1 10
4 4
1 3
2 4
6 7
1 9
2 5
1 1
output
2
3
3
1
3
2
2
3
2
1

CF&&CC百套计划3 Codeforces Round #204 (Div. 1) D. Jeff and Removing Periods的更多相关文章

  1. CF&&CC百套计划3 Codeforces Round #204 (Div. 1) A. Jeff and Rounding

    http://codeforces.com/problemset/problem/351/A 题意: 2*n个数,选n个数上取整,n个数下取整 最小化 abs(取整之后数的和-原来数的和) 先使所有的 ...

  2. CF&&CC百套计划3 Codeforces Round #204 (Div. 1) E. Jeff and Permutation

    http://codeforces.com/contest/351/problem/E 题意: 给出一些数,可以改变任意数的正负,使序列的逆序对数量最少 因为可以任意加负号,所以可以先把所有数看作正数 ...

  3. CF&&CC百套计划3 Codeforces Round #204 (Div. 1) B. Jeff and Furik

    http://codeforces.com/contest/351/problem/B 题意: 给出一个n的排列 第一个人任选两个相邻数交换位置 第二个人有一半的概率交换相邻的第一个数>第二个数 ...

  4. CF&&CC百套计划4 Codeforces Round #276 (Div. 1) A. Bits

    http://codeforces.com/contest/484/problem/A 题意: 询问[a,b]中二进制位1最多且最小的数 贪心,假设开始每一位都是1 从高位i开始枚举, 如果当前数&g ...

  5. CF&&CC百套计划4 Codeforces Round #276 (Div. 1) E. Sign on Fence

    http://codeforces.com/contest/484/problem/E 题意: 给出n个数,查询最大的在区间[l,r]内,长为w的子区间的最小值 第i棵线段树表示>=i的数 维护 ...

  6. CF&&CC百套计划1 Codeforces Round #449 C. Willem, Chtholly and Seniorious (Old Driver Tree)

    http://codeforces.com/problemset/problem/896/C 题意: 对于一个随机序列,执行以下操作: 区间赋值 区间加 区间求第k小 区间求k次幂的和 对于随机序列, ...

  7. CF&&CC百套计划1 Codeforces Round #449 B. Ithea Plays With Chtholly

    http://codeforces.com/contest/896/problem/B 题意: 交互题 n张卡片填m个1到c之间的数,1<=n*ceil(c/2)<=m 最后填出一个单调非 ...

  8. CF&&CC百套计划1 Codeforces Round #449 A. Nephren gives a riddle

    http://codeforces.com/contest/896/problem/A 第i个字符串嵌套第i-1个字符串 求第n个字符串的第k个字母 dfs #include<map> # ...

  9. CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries

    https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...

随机推荐

  1. HDU 1015 Jury Compromise 01背包

    题目链接: http://poj.org/problem?id=1015 Jury Compromise Time Limit: 1000MSMemory Limit: 65536K 问题描述 In ...

  2. HDU 2078 复习时间

    http://acm.hdu.edu.cn/showproblem.php?pid=2078 Problem Description 为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑.xh ...

  3. 使用pt-query-digest,找到不是很合适的sql

    pt-query-digest 1.  概述 索引可以我们更快速的执行查询,但是肯定存在不合理的索引,如果想找到那些索引不是很合适的查询,并在它们成为问题前进行优化,则可以使用pt-query-dig ...

  4. 使用Shell脚本删除/清空日志文件

    话不多少,直接上代码: #!/bin/bash workdir=("/home/Tax_Punish_Ret/log_txt") #可填写多个路径, 用空格隔开 # 查找日志文件 ...

  5. delphi如何检索adoquery里面某一列存在的重复行?

    var IsHave:Boolean; begin adoquery.first; while(not adoquery.eof) do begin if(adoquery.fieldbyname(' ...

  6. 时空KSOA之CS表单工具说明

    CS表单工具说明 1.调用: 1.1.单据事件调用 runbill_表单sn 调用无窗口表单 loadbill_表单sn 调用窗口表单 1.2.功能调用 功能号:LOADCSBILL 参数表单名称 1 ...

  7. MySQL的间隙锁

    什么是间隙锁当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁:对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也 ...

  8. 重新认识javascript的settimeout和异步

    1.简单的settimeout setTimeout(function () { while (true) { } }, 1000); setTimeout(function () { alert(' ...

  9. Xwork概况 XWork是一个标准的Command模式实现,并且完全从web层脱离出来。Xwork提供了很多核心功能:前端拦截机(interceptor),运行时表单属性验证,类型转换,强大的表达式语言(OGNL – the Object Graph NavigationLanguage),IoC(Inversion of Control反转控制)容器等。 ----------------

    Xwork概况 XWork是一个标准的Command模式实现,并且完全从web层脱离出来.Xwork提供了很多核心功能:前端拦截机(interceptor),运行时表单属性验证,类型转换,强大的表达式 ...

  10. PGM学习之五 贝叶斯网络

    本文的主题是“贝叶斯网络”(Bayesian Network) 贝叶斯网络是一个典型的图模型,它对感兴趣变量(variables of interest)及变量之间的关系(relationships) ...