CF&&CC百套计划3 Codeforces Round #204 (Div. 1) D. Jeff and Removing Periods

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=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-‘0‘; 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=1;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=1;i<=n;++i) last[i]=n+1;
    fr[n+1]=n+1;
    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+1) fr[i]=fr[bac[i]];
        else fr[i]=bac[bac[i]];
    }
    int m;
    read(m);
    for(int i=1;i<=m;++i)
    {
        read(e[i].l);
        read(e[i].r);
        e[i].id=i;
    }
    int siz=sqrt(n);
    for(int i=1;i<=n;++i) bl[i]=(i-1)/siz+1;
    sort(e+1,e+m+1,cmp);
    int L=1,R=0,tmp=0,dengcha=0;
    for(int j=1;j<=m;++j)
    {
        x=e[j].l; y=e[j].r;

            for(int i=L-1;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]]==1)
                {
                    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]]==1)
                {
                    dengcha--;
                    tmp--;
                }
                else
                {
                    if(fl[i]>=x && fl[pre[i]]<x) dengcha++;
                }
                sum[val[i]]--;
            }
            for(int i=R+1;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+1;
        if(dengcha>0) ans[e[j].id]--;
    }
    for(int i=1;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

52 2 1 1 251 51 12 21 32 3

output

21122

input

102 1 3 3 3 3 1 3 1 1104 82 101 104 41 32 46 71 92 51 1

output

2331322321
时间: 2024-10-12 19:26:11

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

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

http://codeforces.com/problemset/problem/351/A 题意: 2*n个数,选n个数上取整,n个数下取整 最小化 abs(取整之后数的和-原来数的和) 先使所有的数都下取整,累积更改的sum 那么选1个小数上取整,就会使sum-1 整数上下取整不会产生影响 所以有1个整数就可以使上取整的小数少1个 所以ans=min(abs(i-sum)) i∈[n-整数个数,n] #include<cmath> #include<cstdio> #inclu

CF&amp;&amp;CC百套计划2 CodeChef December Challenge 2017 Chef And his Cake

https://www.codechef.com/DEC17/problems/GIT01 #include<cstdio> #include<algorithm> using namespace std; #define N 101 char s[N]; int main() { int T; scanf("%d",&T); int n,m; int OddG,OddR,EvenG,EvenR; int ans; while(T--) { OddG=O

CF&amp;&amp;CC百套计划2 CodeChef December Challenge 2017 Chef and Hamming Distance of arrays

https://www.codechef.com/DEC17/problems/CHEFHAM #include<cstdio> #include<cstring> #include<iostream> using namespace std; #define N 100001 int a[N],b[N]; int sum[N],wh[N][2]; int num1[N],num2[N]; void read(int &x) { x=0; char c=getc

CF&amp;&amp;CC百套计划2 CodeChef December Challenge 2017 Total Diamonds

https://www.codechef.com/DEC17/problems/VK18 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 1000001 long long sum[N*2],dp[N]; int num[11]; void read(int &x) { x=0; char c=getchar(); while(!isdi

CF&amp;&amp;CC百套计划2 CodeChef December Challenge 2017 Penalty Shoot-out

https://www.codechef.com/DEC17/problems/CPLAY #include<cstdio> #include<algorithm> using namespace std; char s[21]; int main() { int sumA,sumB; while(scanf("%s",s+1)!=EOF) { sumA=sumB=0; int i; for(i=1;i<=10;++i) { if(i&1) { i

cf之路,1,Codeforces Round #345 (Div. 2)

 cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....       其实这个应该是昨天就写完的,不过没时间了,就留到了今天.. 地址:http://codeforces.com/contest/651/problem/A A. Joysticks time limit per test 1 second memory limit per test 256

【打CF,学算法——一星级】Codeforces Round #313 (Div. 2) A. Currency System in Geraldion

[CF简单介绍] 提交链接:http://codeforces.com/contest/560/problem/A 题面: A. Currency System in Geraldion time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A magic island Geraldion, where Gerald lives,

【打CF,学算法——二星级】Codeforces Round #313 (Div. 2) B. Gerald is into Art(水题)

[CF简单介绍] 提交链接:http://codeforces.com/contest/560/problem/B 题面: B. Gerald is into Art time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Gerald bought two very rare paintings at the Sotheby's a

小蒟蒻初次CF滚粗+爆炸记 (Codeforces Round #466 Div.2)

比赛链接:http://codeforces.com/blog/entry/57981 小蒟蒻今天初次在ZCDHJ张大佬的带领下,打了一场CF (张大佬cnblogs链接:https://www.cnblogs.com/ZCDHJ)' 英文完全看不懂,后面几题直接放弃,各位dalao请见谅 T1: 题目链接:http://codeforces.com/contest/940/problem/A 题目大意: 给你一个n个数的集合,要求你删掉若干数,其中最大的差不应该超过d,求最小删除量. (小蒟蒻