zoukankan      html  css  js  c++  java
  • 「LibreOJ β Round」ZQC 的截图(随机+hash)

    https://loj.ac/problem/502

    暴力的做法就是可持久化线段树,可惜空间爆了。

    考虑给每个颜色随机一个权值,若到根路径的权值和是3的倍数,则说明这条路径可能所有颜色的出现次数是3的倍数。

    一次的错误率是(1/3),显然太高了。
    但我们可以多搞几维,把权值变成了(w)维的向量,则正确率是((1-{1over 3^w})^m)

    对于查询一个的,可以预先把每个颜色的1、2次的向量丢进一个hash表,每次查询即可,正确率((1-{nover 3^w})^m)

    (w)(16*3)时,可以用三个int压位存向量,可以预处理(3^6*3^6)的转移矩阵以加速向量不进位加法。

    Code:


    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    #define gc getchar
    template<class T> void read(T &x) {
    	char c = ' '; x = 0; int f = 1;
    	while((c < '0' || c > '9') && c != '-') c = gc();
    	if(c == '-') f = -1, c = gc();
    	for(; c >= '0' && c <= '9'; c = gc()) x = x * 10 + c - '0';
    	x *= f;
    }
    
    const int w = 729;
    
    int a3[7];
    
    int ja[w][w];
    
    struct P {
    	int x, y, z;
    	P(int _x = 0, int _y = 0, int _z = 0) {
    		x = _x, y = _y, z = _z;
    	}
    };
    
    void build() {
    	a3[0] = 1; fo(i, 1, 6) a3[i] = a3[i - 1] * 3;
    	ff(i, 0, w) ff(j, 0, w) {
    		int s = 0;
    		ff(k, 0, 6) {
    			int x = (i / a3[k] % 3 + j / a3[k] % 3) % 3;
    			s += x * a3[k];
    		}
    		ja[i][j] = s;
    	}
    }
    
    int calc(int x, int y) {
    	return ja[x / w / w][y / w / w] * w * w + ja[x / w % w][y / w % w] * w + ja[x % w][y % w];
    }
    
    P operator + (P a, P b) {
    	return P(calc(a.x, b.x), calc(a.y, b.y), calc(a.z, b.z));
    }
    
    bool operator == (P a, P b) {
    	return a.x == b.x && a.y == b.y;
    }
    
    int rd() {
    	return rand() % w * w * w + rand() % w * w + rand() % w;
    }
    
    const int N = 2e6 + 5;
    
    int n, m;
    P f[N], g[N * 2];
    
    const int M = 7260718;
    
    int h[M];
    
    int ha(P a) {
    	int y = (a.x + a.y) % M;
    	while(h[y] != 0 && !(f[h[y]] == a))	
    		y = (y + 1) % M;
    	return y;
    }
    
    int main() {
    	srand(time(0) + clock());
    	build();
    	scanf("%d %d", &n, &m);
    	fo(i, 1, n) {
    		f[i] = P(rd(), rd(), rd());
    		f[n + i] = f[i] + f[i];
    		int y = ha(f[i]);
    		h[y] = i;
    		y = ha(f[n + i]);
    		h[y] = n + i;
    	}
    	int ans = 0;
    	fo(i, 1, m) {
    		int x, y;
    		read(x); read(y);
    		x ^= ans, y ^= ans;
    		g[i] = g[y] + f[x];
    		if(g[i].x == 0 && g[i].y == 0) {
    			ans = -1;
    		} else {
    			int y = ha(g[i]);
    			if(h[y]) {
    				ans = h[y] > n ? h[y] - n : h[y];
    			} else ans = -2;
    		}
    		pp("%d
    ", ans);
    	}
    }
    
  • 相关阅读:
    希尔伯特空间(Hilbert Space)
    深度神经网络:特点、问题及解决
    深度神经网络:特点、问题及解决
    中英文对照 —— 手机 App/PC 端软件(系统)、互联网
    中英文对照 —— 手机 App/PC 端软件(系统)、互联网
    Opencv决策树分类器应用
    OpenCV实现朴素贝叶斯分类器诊断病情
    机器学习的实现(语言及库的选择)
    机器学习的实现(语言及库的选择)
    《The Economist》的阅读
  • 原文地址:https://www.cnblogs.com/coldchair/p/12659406.html
Copyright © 2011-2022 走看看