zoukankan      html  css  js  c++  java
  • [10.3模拟赛]T1

    Description

    (Jim)是一个热爱打游戏的小伙子,可惜他的游戏水平不太行,以至于经常在游戏里被别人欺负。
    而且(Jim)不仅游戏玩的菜,他还很爱喷人,但是由于自己的垃圾操作,他又喷不过别人。
    为了改善这种局面,(Jim)决定成为一个腿部挂件(俗称抱大腿)。
    已知现在有(N)个选手可供Jim选择,每位选手的能力值为(ai)
    (N)位选手不一定每位选手都有时间配(Jim)玩游戏而且(Jim)的状态也时好时坏,所以(Jim)(Q)个询问,每个询问是(3)个数(X)(L)(R),求第(L)个人到第(R)个人这(R-L+1)个人中与(Jim)配合后的能力值最大是多少,(Jim)与第i位选手配合后的能力值为(ai)(X)进行异或运算((Xor))

    Input

    (1)行:(2)个数(N),(Q)中间用空格分隔,分别表示选手个数及查询的数量((1≤N≤200000,1≤Q≤200000))
    (2)行:共N个数为每个选手能力值中间用空格分隔,对应(ai(0≤a[i]≤10^9))
    (N+2-N+Q+1)行:每行(3)个数(X,L,R),中间用空格分隔。((0≤X≤10^9,0≤L≤R<N))

    Output

    输出共(Q)行,对应每次询问所能得到的最大能力值。

    Sample Input

    9 8
    2 15 4 12 0 6 0 16 12
    2 2 5
    4 8 8
    16 5 8
    16 6 8
    1 0 5
    12 3 4
    15 1 1
    5 0 4

    Sample Output

    14
    8
    28
    28
    14
    12
    0
    10

    Data Constraint

    对于 (20\%) 的数据保证((1 leq N leq 5000,1 leq Q leq 5000))
    对于 (45\%) 的数据保证((1 leq N leq 50000,1 leq Q leq 50000))
    对于 (100\%) 的数据保证((1 leq N leq 200000,1 leq Q leq 200000))

    Limit

    (2000)ms 256M

    Solution

    考场上脑子坏了,只写出了(n^{0.5}ast nast logn),用莫队维护当前的区间,保证只有区间的内的数在(01tire)上。
    看完题解才知道自己写过差不多的原题,真的是失了智。
    老套路,用可持久(01trie)维护节点,用(pre)维护区间就行了

    Code

    上一下考场代码

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define M 30
    #define MAXN 5000000
    int n, m, BASE, x, l, r, cnt;
    int a[MAXN], tot[MAXN], trie[MAXN][2];
    struct rec {
    	int x, l, r, base, num, ans;
    } q[MAXN];
    inline int read() {
    	int s = 0, w = 1;
    	char c = getchar();
    	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    	return s * w;
    }
    inline bool cmp1(rec x, rec y) {
    	return x.base == y.base ? x.r < y.r : x.base < y.base;
    }
    inline bool cmp2(rec x, rec y) {
    	return x.num < y.num;
    }
    inline void Add(int x) {
    	int now = 0;
    	for (register int i = M; i >= 1; i--) {
    		int h = x & (1 << (i - 1)); if (h) h = 1;
    		if (!trie[now][h]) ++cnt, trie[now][h] = cnt;
    		now = trie[now][h];
    		tot[now]++;
    	}
    }
    inline void Delete(int x) {
    	int now = 0;
    	for (register int i = M; i >= 1; i--) {
    		int h = x & (1 << (i - 1)); if (h) h = 1;
    		now = trie[now][h];
    		tot[now]--;
    	}
    }
    inline int Query(int x) {
    	int now = 0, ans = 0;
    	for (register int i = M; i >= 1; i--) {
    		int h = x & (1 << (i - 1)); if (h) h = 1;
    		if (tot[trie[now][!h]])
    			ans += (!h) * 1 << (i - 1), now = trie[now][!h];
    		else
    			ans += h * 1 << (i - 1), now = trie[now][h];
    	}
    	return ans;
    }
    int main() {
    	n = read(), m = read();
    	BASE = sqrt(n);
    	for (register int i = 1; i <= n; i++)
    		a[i] = read();
    	for (register int i = 1; i <= m; i++)
    		q[i].x = read(), q[i].l = read() + 1, q[i].r = read() + 1, q[i].base = q[i].l / BASE, q[i].num = i;
    	sort(q + 1, q + m + 1, cmp1);
    	l = 1, r = 1, Add(a[1]);
    	for (register int i = 1; i <= m; i++) {
    		while (r < q[i].r) { r++; Add(a[r]); }
    		while (r > q[i].r) { Delete(a[r]); r--; }
    		while (l < q[i].l) { Delete(a[l]); l++; }
    		while (l > q[i].l) { l--; Add(a[l]); }
    		q[i].ans = Query(q[i].x) ^ q[i].x;
    	}
    	sort(q + 1, q + m + 1, cmp2);
    	for (register int i = 1; i <= m; i++)
    		printf("%d
    ", q[i].ans);
    	return 0;
    }
    

    可持久化(01trie)

    只要有想见的人,就不是孤身一人了。
  • 相关阅读:
    现代软件工程 第一章 概论 第4题——邓琨
    现代软件工程 第一章 概论 第9题——邓琨
    现代软件工程 第一章 概论 第7题——张星星
    现代软件工程 第一章 概论 第5题——韩婧
    hdu 5821 Ball 贪心(多校)
    hdu 1074 Doing Homework 状压dp
    hdu 1074 Doing Homework 状压dp
    hdu 1069 Monkey and Banana LIS变形
    最长上升子序列的初步学习
    hdu 1024 Max Sum Plus Plus(m段最大子列和)
  • 原文地址:https://www.cnblogs.com/Agakiss/p/11794273.html
Copyright © 2011-2022 走看看