1 条题解

  • 0
    @ 2025-4-12 23:57:50

    对于每一个右端点,我们可以使用毛毛虫算法批量处理一个最近的左端点,满足这一段正好为八个不同的数字,记录在 fif_i 内。

    对于一组查询 [l,r][l,r] ,只要 lfr l \leq f_r 即可对答案贡献 +1+1 。若暴力枚举最坏复杂度为 O(qn/8)O(qn/8) ,用倍增优化即可。

    时间复杂度:O(qlogn)O(qlogn)

    const int maxn = 2e5 + 7, maxm = 22;
    int n, q, a[maxn], f[maxn][maxm + 1];
    
    void solve()
    {
    	cin >> n >> q;
    	for (int i = 2; i <= n + 1; i++)
    		cin >> a[i];
    
    	int j = n + 1;
    	unordered_map<int, int> st;
    	for (int i = n + 1; i >= 2; i--)
    	{
    		while (j > 1 && st.size() < 8)
    			st[a[j--]]++;
    
    		if (j == 1 && st.size() < 8)
    			break;
    
    		f[i][0] = j;
    
    		st[a[i]]--;
    		if (st[a[i]] == 0)
    			st.erase(a[i]);
    	}
    
    	for (int j = 1; j <= maxm; j++)
    		for (int i = 0; i <= n + 1; i++)
    			f[i][j] = f[f[i][j - 1]][j - 1];
    
    	for (int i = 1; i <= q; i++)
    	{
    		int l, r, ans = 0;
    		cin >> l >> r;
    
    		l += 1, r += 1;
    		for (int j = maxm; j >= 0; j--)
    			if (l - 1 <= f[r][j])
    				r = f[r][j], ans += 1 << j;
    		cout << ans << endl;
    	}
    }
    
    • 1

    信息

    ID
    18
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者