HDU

HDU - 5790

前缀总和为o(n)级别的, 然后把前缀hash一下变成求区间本质不同数字的个数。

或者不用hash丢到字典树上去就好了。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

const int B = (int)1e9 + 9;

int n;
string s[N];
vector<ull> hs[N];
map<ull, int> Map;
char t[N];

int Rt[N], treecnt;
struct Node {
    int sum, ls, rs;
} a[N * 40];

void update(int p, int val, int l, int r, int &x, int y) {
    x = ++treecnt;
    a[x] = a[y];
    a[x].sum += val;
    if(l == r) return;
    int mid = l + r >> 1;
    if(p <= mid) update(p, val, l, mid, a[x].ls, a[y].ls);
    else update(p, val, mid + 1, r, a[x].rs, a[y].rs);
}

int query(int L, int R, int l, int r, int x) {
    if(!x || R < l || r < L) return 0;
    if(L <= l && r <= R) return a[x].sum;
    int mid = l + r >> 1;
    return query(L, R, l, mid, a[x].ls) + query(L, R, mid + 1, r, a[x].rs);
}

void init() {
    Map.clear();
    treecnt = 0;
}

int main() {
    while(scanf("%d", &n) != EOF) {
        init();
        for(int i = 1; i <= n; i++) {
            scanf("%s", t);
            s[i] = t;
        }
        for(int i = 1; i <= n; i++) {
            hs[i].resize(SZ(s[i]));
            hs[i][0] = s[i][0];
            for(int j = 1; j < SZ(s[i]); j++) {
                hs[i][j] = hs[i][j - 1] * B + s[i][j];
            }
        }
        for(int i = 1, j; i <= n; i++) {
            Rt[i] = Rt[i - 1];
            for(auto &t : hs[i]) {
                j = Map[t];
                update(i, 1, 1, n, Rt[i], Rt[i]);
                if(j) update(j, -1, 1, n, Rt[i], Rt[i]);
                Map[t] = i;
            }
        }
        int q, Z = 0;
        scanf("%d", &q);
        while(q--) {
            int L, R;
            scanf("%d%d", &L, &R);
            L = (Z + L) % n + 1;
            R = (Z + R) % n + 1;
            if(L > R) swap(L, R);
            Z = query(L, R, 1, n, Rt[R]);
            printf("%d
", Z);
        }
    }
    return 0;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/11491762.html