4184: shallot 线段树+按时间分治+线性基

来源:互联网 发布:带上她的眼睛知乎 编辑:程序博客网 时间:2024/06/05 01:11

Oxer大爷安利的题 qwq。
了解了一下按时间分治。
由于每个数的出现区间一定是连续的一段,那么可以在线段树上对应节点插入这个数,也就是每个节点套一个vector。然后dfs一下把根到叶子路径上所有经过的点都插入线性基里,就可以求答案了。

#include<iostream>#include<cstdio>#include<set>#include<vector>using namespace std;const int N=500005;int n;int l[N<<2],r[N<<2];vector<int> a[N<<2];set<pair<int,int> > s;struct node{    int a[31];    int& operator[](int x)    {        return a[x];    }}ins;inline int read(){    int a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}void build(int k,int x,int y){    l[k]=x; r[k]=y;    if (l[k]==r[k]) return;    int mid=l[k]+r[k]>>1;    build(k<<1,x,mid); build(k<<1|1,mid+1,y);}void insert(int k,int x,int y,int val){    if (l[k]==x&&r[k]==y)    {        a[k].push_back(val);        return;    }    int mid=l[k]+r[k]>>1;    if (y<=mid) insert(k<<1,x,y,val);    else if (x>mid) insert(k<<1|1,x,y,val);    else insert(k<<1,x,mid,val),insert(k<<1|1,mid+1,y,val);}inline node add(node ins,int x){    for (int i=30;~i;i--)        if ((1<<i)&x)        {            if (!ins[i])            {                ins[i]=x;                break;            }            else x^=ins[i];        }    return ins;}void dfs(int k,node ins){    for (int i=0;i<a[k].size();i++)        ins=add(ins,a[k][i]);    if (l[k]==r[k])    {        int ans=0;        for (int i=30;~i;i--)            if ((ans^ins[i])>ans) ans^=ins[i];        printf("%d\n",ans);        return;    }    dfs(k<<1,ins); dfs(k<<1|1,ins);}int main(){    n=read();    build(1,1,n);    for (int i=1;i<=n;i++)    {        int x=read();        if (x>0) s.insert(make_pair(x,i));        else        {            pair<int,int> last=*s.lower_bound(make_pair(-x,0));            insert(1,last.second,i-1,-x);            s.erase(last);        }    }    for (set<pair<int,int> >::iterator it=s.begin();it!=s.end();it++)        insert(1,it->second,n,it->first);    dfs(1,ins);    return 0;}
0 0
原创粉丝点击