• CF1093E Intersection of Permutations [分块 +bitset]


    大家好, 我非常喜欢暴力数据结构, 于是就用分块A了此题

    分块题,考虑前缀和 (b_i) 表示 bitset 即 (0) ~ (i ) 出现过的数字,然后考虑直接暴力复制块然后前缀和,修改也很简单,直接删除完了 swap 一下,再弄回去

    时间复杂度 (O(q sqrt n + q frac{n}{w}))

    // by Isaunoya
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include <cstdio>
    #include <bitset>
    
    using namespace std;
    
    #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
    #define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
    //#define int long long
    
    const int _ = 1 << 21;
    struct I {
    	char fin[_], *p1 = fin, *p2 = fin;
    	inline char gc() {
    		return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
    	}
    	inline I& operator>>(int& x) {
    		bool sign = 1;
    		char c = 0;
    		while (c < 48) ((c = gc()) == 45) && (sign = 0);
    		x = (c & 15);
    		while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
    		x = sign ? x : -x;
    		return *this;
    	}
    	inline I& operator>>(double& x) {
    		bool sign = 1;
    		char c = 0;
    		while (c < 48) ((c = gc()) == 45) && (sign = 0);
    		x = (c - 48);
    		while ((c = gc()) > 47) x = x * 10 + (c - 48);
    		if (c == '.') {
    			double d = 1.0;
    			while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
    		}
    		x = sign ? x : -x;
    		return *this;
    	}
    	inline I& operator>>(char& x) {
    		do
    			x = gc();
    		while (isspace(x));
    		return *this;
    	}
    	inline I& operator>>(string& s) {
    		s = "";
    		char c = gc();
    		while (isspace(c)) c = gc();
    		while (!isspace(c) && c != EOF) s += c, c = gc();
    		return *this;
    	}
    } in;
    struct O {
    	char st[100], fout[_];
    	signed stk = 0, top = 0;
    	inline void flush() {
    		fwrite(fout, 1, top, stdout), fflush(stdout), top = 0;
    	}
    	inline O& operator<<(int x) {
    		if (top > (1 << 20)) flush();
    		if (x < 0) fout[top++] = 45, x = -x;
    		do
    			st[++stk] = x % 10 ^ 48, x /= 10;
    		while (x);
    		while (stk) fout[top++] = st[stk--];
    		return *this;
    	}
    	inline O& operator<<(char x) {
    		fout[top++] = x;
    		return *this;
    	}
    	inline O& operator<<(string s) {
    		if (top > (1 << 20)) flush();
    		for (char x : s) fout[top++] = x;
    		return *this;
    	}
    } out;
    #define pb emplace_back
    #define fir first
    #define sec second
    
    template < class T > inline void cmax(T & x , const T & y) {
    	(x < y) && (x = y) ;
    }
    template < class T > inline void cmin(T & x , const T & y) {
    	(x > y) && (x = y) ;
    }
    
    int n , m ;
    const int maxn = 2e5 + 200 ;
    template < int bl > 
    struct BLOCK {
    	bitset < maxn > b[maxn / bl] ;
    	bitset < maxn > temp ;
    	int per[maxn] ;
    	inline void ins(int x , int v) {
    		per[x] = v ;
    		for(register int i = x ; i <= n ; i += bl)
    			b[i / bl].set(v) ;
    	}
    	inline void del(int x , int v)  {
    		for(register int i = x ; i <= n ; i += bl)
    			b[i / bl].reset(v) ;
    	}
    	inline bitset < maxn > qry(int x) {
    		temp = x / bl ? b[x / bl - 1] : 0 ;
    		rep(i , max(x / bl * bl , 1) , x) 
    			temp.set(per[i]) ;
    		return temp ;
    	}
    	inline bitset < maxn > qry(int l , int r) {
    		return qry(r) ^ qry(l - 1) ;
    	}
    };
    int a[maxn] , b[maxn] ;
    BLOCK < 256 > A ;
    BLOCK < 512 > B ;
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #endif
    	in >> n >> m ;
    	rep(i , 1 , n) in >> a[i] , A.ins(i , a[i]) ;
    	rep(i , 1 , n) in >> b[i] , B.ins(i , b[i]) ;
    	while(m --) {
    		int opt ;
    		in >> opt ;
    		if(opt == 1) {
    			int l , r , a , b ;
    			in >> l >> r >> a >> b ;
    			int ans = (A.qry(l , r) & B.qry(a , b)).count() ;
    			out << ans << '
    ' ;
    		}
    		else {
    			int x , y ;
    			in >> x >> y ;
    			B.del(x , b[x]) ; B.del(y , b[y]) ;
    			swap(b[x] , b[y]) ;
    			B.ins(x , b[x]) ; B.ins(y , b[y]) ;
    		}
    	}
    	return out.flush(), 0;
    }
    
    
  • 相关阅读:
    JS 寻路算法
    Fireworks基本使用
    html基础知识汇总(二)之Emmet语法
    JS函数式编程
    Web前端导航
    CSS样式一
    选择器的分类
    框架集
    表单标签元素
    图像热点&图像映射
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12186818.html
Copyright © 2020-2023  润新知