zoukankan      html  css  js  c++  java
  • Solution -「LOCAL」「cov. HDU 6816」折纸游戏

    (mathcal{Description})

      Link(削弱版).

      (n) 张纸叠在一起对折 (k) 次,然后从上到下为每层的正反两面写上数字,求把纸重新摊平后每张纸上的数字序列。

      (nle10)(kle19)

    (mathcal{Solution})

      模拟摊平操作,对于每一层维护一个双向链表(实际指针的方向并不重要,不要纠结两个叫 pre 的指针相互指的问题),每次把上一半的反向接到下一半即可。

      复杂度 (mathcal O(n2^k)),瓶颈在 IO。

    (mathcal{Code})

    #include <cstdio>
    #include <vector>
    #include <assert.h>
    
    typedef unsigned long long ULL;
    
    inline char fgc () {
    	static char buf[1 << 17], *p = buf, *q = buf;
    	return p == q && ( q = buf + fread ( p = buf, 1, 1 << 17, stdin ), p == q ) ? EOF : *p ++;
    }
    
    inline ULL rint () {
    	ULL x = 0; char s = fgc ();
    	for ( ; s < '0' || '9' < s; s = fgc () );
    	for ( ; '0' <= s && s <= '9'; s = fgc () ) x = x * 10 + ( s ^ '0' );
    	return x;
    }
    
    inline void wint ( const ULL x ) {
    	if ( 9 < x ) wint ( x / 10 );
    	putchar ( x % 10 ^ '0' );
    }
    
    const int MAXN = 10, MAXK = 19, MAXP = 1 << MAXK << 1, MAXL = MAXN << MAXK << 1;
    int n, K, perL, L, p[MAXL + 5];
    int pre[MAXP + 5], suf[MAXP + 5], lef[MAXP + 5], rig[MAXP + 5];
    std::vector<int> paper[MAXN + 5], fold;
    
    namespace Generator {
    
    const int threshold = 10000000;
    ULL k1,k2;
    
    ULL xorShift128Plus () {
    	ULL k3 = k1, k4 = k2;
    	k1 = k4, k3 ^= k3 << 23;
    	k2 = k3 ^ k4 ^ ( k3 >> 17 ) ^ ( k4 >> 26 );
    	return k2 + k4;
    }
    
    void gen ( int n, int k, ULL _k1, ULL _k2){
    	k1 = _k1, k2 = _k2;
    	int _len = 2 * n * ( 1 << k );
    	for ( int i = 1; i <= _len; i ++ )
    	 p[i] = xorShift128Plus () % threshold + 1;
    }
    
    };
    
    inline void initFold ( std::vector<int>& res ) {
    	int up = perL;
    	for ( int i = up; i; -- i ) {
    		lef[i] = rig[i] = up - i + 1;
    		pre[i] = suf[i] = 0;
    	}
    	while ( up > 2 ) {
    		int mid = up >> 1;
    		for ( int i = mid + 1; i <= up; ++ i ) {
    			int j = mid * 2 + 1 - i;
    			if ( !suf[lef[i]] ) {
    				assert ( !suf[lef[j]] );
    				suf[lef[i]] = lef[j], suf[lef[j]] = lef[i];
    			} else {
    				assert ( !pre[lef[i]] && !pre[lef[j]] );
    				pre[lef[i]] = lef[j], pre[lef[j]] = lef[i];
    			}
    			lef[j] = rig[i];
    		}
    		up = mid;
    	}
    	int i = lef[1], las = 0;
    	for ( int i = lef[2], las = 0; ; ) {
    		res.push_back ( i );
    		if ( i == rig[2] ) break;
    		int nxt = suf[i] ^ las ? suf[i] : pre[i];
    		las = i, i = nxt;
    	}
    	for ( int i = lef[1], las = 0; ; ) {
    		res.push_back ( i );
    		if ( i == rig[1] ) break;
    		int nxt = suf[i] ^ las ? suf[i] : pre[i];
    		las = i, i = nxt;
    	}
    }
    
    int main () {
    	 freopen ( "folding.in", "r", stdin );
    	 freopen ( "folding.out", "w", stdout );
    	for ( int T = rint (), type = rint (); T --; ) {
    		n = rint (), K = rint (), perL = 1 << K << 1, L = n * perL;
    		if ( !type ) for ( int i = 1; i <= L; ++ i ) p[i] = rint ();
    		else {
    			ULL k1 = rint (), k2 = rint ();
    			Generator::gen ( n, K, k1, k2 );
    		}
    		for ( int i = 1; i <= L; ++ i ) { // attention that K>0.
    			int r = ( i - 1 ) % ( n << 2 ) + 1;
    			if ( r <= n << 1 ) {
    				paper[n - ( r - 1 ) / 2].push_back ( p[i] );
    			} else {
    				paper[( r - ( n << 1 ) - 1 ) / 2 + 1].push_back ( p[i] );
    			}
    		}
    		initFold ( fold );
    		ULL ans = 0;
    		for ( int i = 1, id = 0; i <= n; ++ i ) {
    			for ( int j = 0; j < perL; ++ j ) {
    				ans ^= 1ll * ++ id * paper[i][fold[j] - 1];
    			}
    			paper[i].clear ();
    		}
    		wint ( ans ), putchar ( '
    ' );
    	}
    	return 0;
    }
    

    (mathcal{Details})

      为什么这种大模拟兔子会想到去找规律……

      关键是死也没找出来!

      联赛难度联赛难度啊你姿势摆对啊喂 qwq!

  • 相关阅读:
    汉诺塔
    美丽联合2018前端
    游览器
    python多线程实现
    cuda toolkit
    编译器,解释器及混合编译
    大疆无人机
    SaaS PaaS IaaS mes
    CNN中权值共享的理解
    最近动作项目心得
  • 原文地址:https://www.cnblogs.com/rainybunny/p/13568013.html
Copyright © 2011-2022 走看看