• 「luogu4135」作诗


    「luogu4135」作诗

    传送门
    分块好题。
    预处理出 (f[i][j]) 表示 (i) 号块到 (j) 号块的答案,(num[i][k]) 表示 (k) 在前 (i) 块的出现次数,暴力预处理,暴力查询,复杂度 (O(n sqrt n))
    参考代码:

    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    using namespace std;
    template < class T > inline void read(T& s) {
    	s = 0; int f = 0; char c = getchar();
    	while ('0' > c || c > '9') f |= c == '-', c = getchar();
    	while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
    	s = f ? -s : s;
    }
    
    const int _ = 1e5 + 10, __ = 318;
    
    int n, c, q, a[_], Q[_], cnt[_];
    int gap, pos[_], f[__][__], num[__][_];
    
    inline int Query(int l, int r) {
    	int res;
    	if (pos[l] == pos[r]) {
    		res = 0;
    		for (rg int i = l; i <= r; ++i) {
    			++cnt[a[i]];
    			if (cnt[a[i]] != 1) { if (cnt[a[i]] & 1) --res; else ++res; }
    		}
    		for (rg int i = l; i <= r; ++i) cnt[a[i]] = 0;
    	} else {
    		res = f[pos[l] + 1][pos[r] - 1];
    		Q[0] = 0;
    		for (rg int i = l; i <= pos[l] * gap && i <= n; ++i) Q[++Q[0]] = a[i];
    		for (rg int i = (pos[r] - 1) * gap + 1; i <= r; ++i) Q[++Q[0]] = a[i];
    		for (rg int i = 1; i <= Q[0]; ++i) {
    			if (cnt[Q[i]] == 0) {
    				cnt[Q[i]] = num[pos[r] - 1][Q[i]] - num[pos[l]][Q[i]] + 1;
    				if (cnt[Q[i]] != 1) { if (cnt[Q[i]] & 1) --res; else ++res; }
    			} else { ++cnt[Q[i]]; if (cnt[Q[i]] & 1) --res; else ++res; }
    		}
    		for (rg int i = 1; i <= Q[0]; ++i) cnt[Q[i]] = 0;
    	}
    	return res;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	file("poetize");
    #endif
    	read(n), read(c), read(q), gap = sqrt(n);
    	for (rg int i = 1; i <= n; ++i) read(a[i]), pos[i] = (i - 1) / gap + 1;
    	for (rg int i = 1; i <= pos[n]; ++i) {
    		for (rg int j = 1; j <= c; ++j) num[i][j] = num[i - 1][j];
    		for (rg int j = (i - 1) * gap + 1; j <= i * gap; ++j) ++num[i][a[j]];
    	}
    	for (rg int i = 1; i <= pos[n]; ++i)
    		for (rg int j = i; j <= pos[n]; ++j) {
    			f[i][j] = f[i][j - 1];
    			for (rg int k = (j - 1) * gap + 1; k <= j * gap; ++k) {
    				if (cnt[a[k]] == 0) {
    					cnt[a[k]] = num[j - 1][a[k]] - num[i - 1][a[k]] + 1;
    					if (cnt[a[k]] != 1) { if (cnt[a[k]] & 1) --f[i][j]; else ++f[i][j]; }
    				} else { ++cnt[a[k]]; if (cnt[a[k]] & 1) --f[i][j]; else ++f[i][j]; }
    			}
    			for (rg int k = (j - 1) * gap + 1; k <= j * gap; ++k) cnt[a[k]] = 0;
    		}
    	for (rg int ans = 0, l, r; q--; ) {
    		read(l), l = (l + ans) % n + 1;
    		read(r), r = (r + ans) % n + 1;
    		if (l > r) swap(l, r);
    		ans = Query(l, r), printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    能够免费做商业站点的CMS讨论
    ntoskrnl.exe损坏或丢失的解决方式
    QT 仓库管理系统 开放源代码
    Disposable microfluidic devices: fabrication, function, and application Gina S. Fiorini and Daniel T
    DllImport中的EntryPoint
    IOS Table中Cell的重用reuse机制分析
    双slave的server_uuid同样问题
    怎样使用SetTimer MFC 够具体
    2013 成都邀请赛
    设计模式六大原则(2):里氏替换原则
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12231587.html
Copyright © 2020-2023  润新知