BZOJ 4184: shallot

Description

在某时刻加入或删除一个点,问每个时刻的集合中能异或出来的最大值是多少.

Sol

线段树+按时间分治+线性基.

把一个数字的存在时间挂在线段树的区间上,不超过 \(logn\) 个区间,所以总和不超过 \(nlogn\) 个节点信息.

然后从上往下走遍历整个线段树,每次到根节点统计一下答案,这里跟线性基有些不同,线性基转置矩阵就是普通的高斯消元,这时候维护线性基,每次插入一个数,更新的贡献,统计答案的时候从上往下贪心,选一个最大值,而不是回带...

Code

/**************************************************************
    Problem: 4184
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:11256 ms
    Memory:37624 kb
****************************************************************/

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 5e5+50;
const int M = 35;

int n;
map< int,int > mp;
LL pow2[M],ans[N];

struct Py {
    LL b[M];
    Py() { memset(b,0,sizeof(b)); }
    void insert(int x) {
        for(int i=M-1;~i;i--) if(x&pow2[i]) {
            if(!b[i]) { b[i]=x;break; }
            else x^=b[i];
        }
    }
    LL GetAns() {
        LL ans=0;
        for(int i=M-1;~i;i--) if((ans^b[i])>ans) ans^=b[i];
        return ans;
    }
}piyan;
struct SegMentTree {
    vector< int > d[N<<2];
    #define lc (o<<1)
    #define rc (o<<1|1)
    #define mid ((l+r)>>1)

    void insert(int o,int l,int r,int L,int R,int x) {
        if(L<=l && r<=R) return void(d[o].push_back(x));
        if(L<=mid) insert(lc,l,mid,L,R,x);
        if(R>mid) insert(rc,mid+1,r,L,R,x);
    }
    void DFS(int o,int l,int r,Py py) {
        for(vector< int > ::iterator i=d[o].begin();i!=d[o].end();i++) py.insert(*i);
        if(l==r) return void(ans[l]=py.GetAns());
        DFS(lc,l,mid,py),DFS(rc,mid+1,r,py);
    }
}seg;

inline int in(int x=0,char ch=getchar(),int v=1) {
    while(ch>‘9‘ || ch<‘0‘) v=ch==‘-‘ ? -1 : v,ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();return x*v;
}
int main() {
    n=in();
    for(int i=1;i<=n;i++) {
        int x=in();
        if(x>=0) mp[x]=i;
        else x=-x,seg.insert(1,1,n,mp[x],i-1,x),mp.erase(x);
    }
    for(map< int,int > ::iterator i=mp.begin();i!=mp.end();i++)
        if((*i).second) seg.insert(1,1,n,(*i).second,n,(*i).first);
    pow2[0]=1;for(int i=1;i<M;i++) pow2[i]=pow2[i-1]<<1;
    seg.DFS(1,1,n,piyan);
    for(int i=1;i<=n;i++) printf("%lld\n",ans[i]);
    return 0;
}
时间: 2024-10-13 15:58:08

BZOJ 4184: shallot的相关文章

[BZOJ 4184] shallot 以时间为基底建线段树

题意 给定时长 $n$ , 每个时刻有某个元素出现或者消失, 求每个时刻所有元素的最大异或值. $n \le 500000$ . 分析 通过 map 或者 hash , 我们可以知道 $O(n)$ 个 "一个元素 $x$ 在 $[l, r]$ " 出现的信息. 对时间建立线段树, 每个节点开一个 vector , 对区间 $[l, r]$ 对应的所有节点插入一个 $x$ . 对线段树进行 DFS , 同时动态维护线性基. 实现 #include <cstdio> #incl

bzoj 4184: shallot (线段树维护线性基)

题面 \(solution:\) \(code:\) #include<iostream> #include<cstdio> #include<iomanip> #include<algorithm> #include<cstring> #include<cstdlib> #include<ctime> #include<cmath> #include<vector> #include<que

「bzoj 4184: shallot」

权限题 线段树分治加线性基 首先这个题要求删除线性基肯定是没法处理的 于是我们套上一个线段树分治 线段树分治就是一种能够避免删除的神仙操作 我们发现询问是对一个时间的单点询问,而每一个数存在的时间却是一个区间 我们求出来每个数的存在区间,每一个区间对应在线段树上并不会超过\(logn\)段 我们就把这些存活区间插入到线段树里去,标记永久化一下 由于一个线性基也就是\(logn\)的空间,所以我们直接一路把线性基搞下来,中间把标记插入线性基就好了 到叶子结点我们就可以处理询问了 代码 #inclu

CodeForces 1100F Ivan and Burgers

CodeForces题面 Time limit 3000 ms Memory limit 262144 kB Source Codeforces Round #532 (Div. 2) Tags data structures divide and conquer greedy math *2600 Editorial Announcement #1 (en) Announcement #2 (ru) Tutorial #1 (en) Tutorial #2 (ru) Tutorial #3 (

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445

【BZOJ】[HNOI2009]有趣的数列

[算法]Catalan数 [题解] 学了卡特兰数就会啦>_<! 因为奇偶各自递增,所以确定了奇偶各自的数字后排列唯一. 那么就是给2n个数分奇偶了,是不是有点像入栈出栈序呢. 将做偶数标为-1,做奇数标为+1,显然当偶数多于奇数时不合法,因为它压不住后面的奇数. 然后其实这种题目,打表就可知啦--QAQ 然后问题就是求1/(n+1)*C(2n,n)%p了,p不一定是素数. 参考bzoj礼物的解法. 看到网上清一色的素数筛+分解质因数解法,不解了好久,感觉写了假的礼物-- 后来觉得礼物的做法才比

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

BZOJ 1012: [JSOI2008]最大数maxnumber(线段树)

012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MB Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列