zoukankan      html  css  js  c++  java
  • SPOJ 3267

    在这里插入图片描述在这里插入图片描述

    题目大意:

    给出一个 n 表示有 n 个数,然后接下来输入n个数,紧接着输入一个 m 表示有 m 组询问,然后有 m 行,每行输入l r ,要求输出区间[l, r]不同数字的种数有多少。

    解题思路:

    莫队算法,离线扫描即可,将n个数分块,每块 根号n ,然后对询问的区间进行排序,左端点升序排序,相同时再对右端点基于奇偶排序(玄学优化),之后设左指针和右指针和计数数组cnt,根据左右指针的移动来判断种类的加减,注意运算符和优先级(这里是由add 和 del 函数压缩过来的,运算符错一点就会 WA)。

    Code:

    #pragma GCC optimize(2)
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1e6 +50;
    int a[N], cnt[N], belong[N], ans[N], now;
    struct node { int l, r, id; }q[N];
    bool cmp(node a, node b)
    {
    	return belong[a.l] ^ belong[b.l] ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r);
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	int n, m;
    	cin >> n;
    	double size = sqrt(n);
    	int num = ceil(n / size);
    	for (int i = 1; i <= num; i ++)
    		for (int j = (i - 1) * size + 1; j <= i * size; j ++)
    			belong[j] = i;
    	for (int i = 1; i <= n; i ++)
    		cin >> a[i];
    	cin >> m;
    	for  (int i = 1; i <= m; i ++)
    	{
    		cin >> q[i].l >> q[i].r;
    		q[i].id = i;
    	}
    	sort(q + 1, q + 1 + m, cmp);
    	int l = 1, r = 0;
    	for (int i = 1; i <= m; i ++)
    	{
    		int ql = q[i].l, qr = q[i].r;
    		while (l < ql) now -= !-- cnt[a[l ++]];
    		while (l > ql) now += !cnt[a[--l]] ++;
    		while (r < qr) now += !cnt[a[++ r]] ++;
    		while (r > qr) now -= !-- cnt[a[r --]];
    		ans[q[i].id] = now;
    	}
    	for (int i = 1; i <= m; i ++)
    		cout << ans[i] << endl;
    	return 0;
    }
    
  • 相关阅读:
    2019 Multi-University Training Contest 4
    AC自动机
    trie
    Contest1802
    蓝桥杯-某电视台举办了低碳生活大奖赛
    蓝桥杯-有一群海盗(不多于20人),在船上比拼酒量
    蓝桥杯-福尔摩斯到某古堡探险
    蓝桥杯-标题:字符串比较
    蓝桥杯-题目:猜算式
    蓝桥杯-标题:算年龄
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294153.html
Copyright © 2011-2022 走看看