zoukankan      html  css  js  c++  java
  • 写诗

    题面

    达达是T国的公主,平时的一大爱好是作诗。

    由于时间紧迫,达达作完诗之后还要虐OI,于是达达找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗。

    因为达达喜欢对偶,所以达达规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次。

    而且达达认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!)。

    于是达达请你安排选法。

    问题简述:N个数,M组询问,每次询问需要你求出[l,r]中有多少个数出现正偶数次。

    输入格式

    输入第一行包含三个整数n、c以及m,表示文章字数、汉字的种类数、要选择m次。

    第二行有n个整数,每个数A[i]在[1, c]间,代表一个编码为A[i]的汉字。

    接下来m行每行两个整数l和r,设上一个询问的答案为ans(第一个询问时ans=0),令L=(l+ans)mod n+1, R=(r+ans)mod n+1,若L>R,交换L和R,则本次询问为[L,R]。

    输出格式

    输出共m行,每行一个整数,第i个数表示达达第i次能选出的汉字的最多种类数。

    数据范围

    1≤n,c,m≤105
    

    输入样例:

    5 3 5
    1 2 2 3 1
    0 4
    1 2
    2 2
    2 3
    3 5
    

    输出样例:

    2
    0
    0
    0
    1
    

    题解

    和普通的分块没啥区别, 块间直接预处理答案, 块内暴力, 只不过这道题卡的有点紧

    要预处理, s[i][j] 表示在前 i 块, 字母j出现的次数

    f[i][j] 为块 i 到 块 j 的答案

    我一直tle, 主要在两个点

    1.用的map(unordered_map), 尽管最多600+个数,但也相当拖时间, 改为手写的 queue
    2.求f[i][j] 我用的三重循环 i,j,k(字母), 妥妥超时, 应该 (1~j * m) j 去算中间 特判什么时候算贡献(具体看代码)

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    #define fi first
    #define se second
    using namespace std;
    typedef pair<int, int> PII;
    typedef int ll;
    
    const int N = 1e5 + 5, M = 317;
    
    int n, c, k, t, ans;
    int s[320][N], f[320][320];
    int a[N], v[N], q[N], cnt[N];
    
    int main()
    {
        scanf("%d%d%d", &n, &c, &k);
        t = (n - 1) / M + 1;
    
        rep (i, 1, t)
        {
            int nx = min(i * M, n);
            rep (j, (i - 1) * M + 1, nx)
            {
                scanf("%d", a + j);
                ++s[i][a[j]];
            }
    
            rep (j, 1, c) s[i][j] += s[i - 1][j];
    
            int cur = 0, cnt = 0;
            per (j, nx, 1)
            {
                if (v[a[j]]) ++v[a[j]];
                else v[a[j]] = 1, q[++cnt] = a[j];
    
                if (v[a[j]] % 2 == 0) ++cur;
                else if (v[a[j]] > 1) --cur;
    
                if (j % M == 1) f[(j - 1) / M + 1][i] = cur;
            }
    
            rep (j, 1, cnt) v[q[j]] = 0;
        }
    
        while (k--)
        {
            int l, r; scanf("%d%d", &l, &r);
            l = (l + ans) % n + 1, r = (r + ans) % n + 1;
            if (l > r) swap(l, r);
    
            ans = 0; int cnt = 0;
            if (r - l + 1 >= (M << 1))
            {
                int L = (l - 1) / M + 1 + (l % M != 1);
                int R = (r - 1) / M + 1 - (r % M != 0);
                ans = f[L][R];
    
                per (i, (L - 1) * M, l)
                    if (v[a[i]]) ++v[a[i]];
                    else
                    {
                        v[a[i]] = s[R][a[i]] - s[L - 1][a[i]] + 1;
                        q[++cnt] = a[i];
                        if (v[a[i]] > 1 && (v[a[i]] & 1)) --ans;
                    }
    
                rep (i, R * M + 1, r)
                    if (v[a[i]]) ++v[a[i]];
                    else
                    {
                        v[a[i]] = s[R][a[i]] - s[L - 1][a[i]] + 1;
                        q[++cnt] = a[i];
                        if (v[a[i]] > 1 && (v[a[i]] & 1)) --ans;
                    }
            }
            else
                rep (i, l, r)
                    if (v[a[i]]) ++v[a[i]];
                    else v[a[i]] = 1, q[++cnt] = a[i];
    
            rep (i, 1, cnt) ans += (v[q[i]] % 2 == 0), v[q[i]] = 0;
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    p4841 城市规划
    p2619 [国家集训队2]Tree I [wqs二分学习]
    p3723 [AH2017/HNOI2017]礼物
    p5437 【XR-2】约定
    p5349 幂
    数据结构:结构之美
    你所不知道的传输层
    为什么选择这种技术而不选择另一种技术?
    Internet路由-主机路由表和转发表
    计算机网络----数据链路层(三)
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13033806.html
Copyright © 2011-2022 走看看