「分块系列」公主的朋友 解题报告

公主的朋友

Description

Problem

由于\(Wulala\)在上个问题中的精彩表现,公主认为\(Wulala\)是一个很棒的人,就把\(Wulala\)留在 了\(X\)国。这时正好公主的一位传教士朋友来拜访公主,于是想找\(wulala\)帮忙。

\(X\)国如同一条直线,其中有\(n\)个城市,从东向西分别编号为\(1\)\(n\)。而他的国家中有\(m\)种宗教, 每个城市一定会有一种信仰的宗教。 有时候有些城市为了获得更多的认可,会派出信仰本城市宗教的传教士前往其他国家。

\(X\)国的传教士都十分厉害,只要是他途经的地方都会改信他所传播的宗教。 传教士们在路上碰到自己宗教的城市自然就不用传教了,所以每 一个传教士在旅行前都会计算自己可以在多少城市停下来(不包括起始的城市)。

而传教士们都是文科僧,数学是很差的,所以他希望\(Wulala\)能帮他计算。可\(Wulala\)数学也不好,但他又不想在公主面前丢脸,你能帮帮他吗?

Input Data

第一行两个整数\(n\)\(m\)
第二行\(n\)个整数第\(i\)个整数代表第ii个城市信仰的宗教;
第三行一个整数 \(T\) 代表传教士的个数;
接下来 \(T\) 行每行两个整数 \(x\)\(y\)代表 \(x\) 城向 \(y\) 城派遣了一个传教士(保证 \(x<y\))

Output Data

输出\(T\)行,第\(i\)行代表第\(i\)个传教士询问的答案

Input / Output Sample

2 2
1 2
2
1 2
1 2
0
1

Data Limit

对于 30%的数据 \(n \le 100000, m \le 10, T \le100\);
对于 60%的数据 \(n \le 100000, m \le 10, T \le 100000\);
对于 100%的数据 \(n \le 100000, m \le 300, T \le 100000\)

Problem Source

湖南师大附中模拟赛


这又和\(数列分块入门8\)蜜汁相似QAQ

\(^双_经\) $^倍_验 $泛滥成灾啊

这里也不多提,参照\(数列分块入门8\)

代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005

int n, m, d, T;
int a[MAXN], b[MAXN], f[500];
bool v[500];

int FF( int x ){
    return v[b[x]] ? f[b[x]] : a[x];
}

int fun( int l, int r, int c ){
    int ans(0);
    for ( int i = l; i <= r && i <= n; ++i ) ans += FF(i) == c, a[i] = c;
    return ans;
}

int Get( int l, int r, int c ){
    int ans(0);
    if ( b[l] == b[r] ){
        if ( v[b[l]] && f[b[l]] == c ) return r - l + 1;
        
        if ( v[b[l]] ){
            fun( ( b[l] - 1 ) * d + 1, l - 1, f[b[l]] );
            fun( r + 1, b[l] * d, f[b[l]] );
        }
        ans = fun( l, r, c );
        v[b[l]] = 0;
        return ans;
    }
    
    if ( v[b[l]] ) fun( ( b[l] - 1 ) * d + 1, l - 1, f[b[l]] );
    ans += fun( l, b[l] * d, c );
    v[b[l]] = 0;
    
    
    if ( v[b[r]] ) fun( r + 1, min( b[r] * d, n ), f[b[r]] );
    ans += fun( ( b[r] - 1 ) * d + 1, r, c );
    v[b[r]] = 0;
    
    for ( int i = b[l] + 1; i <= b[r] - 1; ++i ){
        if ( !v[i] ){
            for ( int j = ( i - 1 ) * d + 1; b[j] == i; ++j ) ans += a[j] == c, a[j] = c;
            v[i] = 1; f[i] = c;
        } else{
            if ( f[i] == c ) ans += d;
            else f[i] = c;
        }
    }
    return ans;
}

int main(){
    scanf( "%d%d", &n, &m );
    d = (int)sqrt(n);
    for ( int i = 1; i <= n; ++i ){
        scanf( "%d", &a[i] );
        b[i] = ( i - 1 ) / d + 1;
    }
    scanf( "%d", &T );
    while ( T-- ){
        int l, r;
        scanf( "%d%d", &l ,&r );
        printf( "%d\n", Get( l, r, FF(l) ) - 1 );
    }
    return 0;
}

数列分块系列目录

数列分块入门1

数列分块入门2

数列分块入门3

数列分块入门4

数列分块入门5

数列分块入门6

数列分块入门7

数列分块入门8

数列分块入门9

蒲公英

公主的朋友 <-

全部评论

相关推荐

点赞 收藏 评论
分享
正在热议
# 牛客帮帮团来啦!有问必答 #
1151355次浏览 17149人参与
# 通信和硬件还有转码的必要吗 #
11200次浏览 101人参与
# OPPO开奖 #
19197次浏览 267人参与
# 和牛牛一起刷题打卡 #
18946次浏览 1635人参与
# 实习与准备秋招该如何平衡 #
203361次浏览 3625人参与
# 大厂无回复,继续等待还是奔赴小厂 #
4970次浏览 30人参与
# 不去互联网可以去金融科技 #
20344次浏览 255人参与
# 通信硬件薪资爆料 #
265887次浏览 2484人参与
# 国企是理工四大天坑的最好选择吗 #
2220次浏览 34人参与
# 互联网公司评价 #
97677次浏览 1280人参与
# 简历无回复,你会继续海投还是优化再投? #
25035次浏览 354人参与
# 0offer是寒冬太冷还是我太菜 #
454843次浏览 5124人参与
# 国企和大厂硬件兄弟怎么选? #
53898次浏览 1012人参与
# 参加过提前批的机械人,你们还参加秋招么 #
14644次浏览 349人参与
# 硬件人的简历怎么写 #
82285次浏览 852人参与
# 面试被问第一学历差时该怎么回答 #
19395次浏览 213人参与
# 你见过最离谱的招聘要求是什么? #
28073次浏览 248人参与
# 学历对求职的影响 #
161229次浏览 1804人参与
# 你收到了团子的OC了吗 #
538690次浏览 6386人参与
# 你已经投递多少份简历了 #
344192次浏览 4963人参与
# 实习生应该准时下班吗 #
96968次浏览 722人参与
# 听劝,我这个简历该怎么改? #
63519次浏览 622人参与
牛客网
牛客企业服务