「分塊系列」公主的朋友 解題報告

公主的朋友

Description

Problem

因爲\(Wulala\)在上個問題中的精彩表現,公主認爲\(Wulala\)是一個很棒的人,就把\(Wulala\)留在 了\(X\)國。這時正好公主的一位傳教士朋友來拜訪公主,因而想找\(wulala\)幫忙。html

\(X\)國如同一條直線,其中有\(n\)個城市,從東向西分別編號爲\(1\)\(n\)。而他的國家中有\(m\)種宗教, 每一個城市必定會有一種信仰的宗教。 有時候有些城市爲了得到更多的承認,會派出信仰本城市宗教的傳教士前往其餘國家。c++

\(X\)國的傳教士都十分厲害,只要是他途經的地方都會改信他所傳播的宗教。 傳教士們在路上碰到本身宗教的城市天然就不用傳教了,因此每 一個傳教士在旅行前都會計算本身能夠在多少城市停下來(不包括起始的城市)。spa

而傳教士們都是文科僧,數學是不好的,因此他但願\(Wulala\)能幫他計算。可\(Wulala\)數學也很差,但他又不想在公主面前丟臉,你能幫幫他嗎?code

Input Data

第一行兩個整數\(n\)\(m\)
第二行\(n\)個整數第\(i\)個整數表明第ii個城市信仰的宗教;
第三行一個整數 \(T\) 表明傳教士的個數;
接下來 \(T\) 行每行兩個整數 \(x\)\(y\)表明 \(x\) 城向 \(y\) 城派遣了一個傳教士(保證 \(x<y\))htm

Output Data

輸出\(T\)行,第\(i\)行表明第\(i\)個傳教士詢問的答案blog

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\)ip

Problem Source

湖南師大附中模擬賽get


這又和\(數列分塊入門8\)蜜汁類似QAQinput

\(^雙_經\) $^倍_驗 $氾濫成災啊數學

這裏也很少提,參照\(數列分塊入門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

蒲公英

公主的朋友 <-

相關文章
相關標籤/搜索