bzoj4184

题解:

按时间分治线段树

然后线性基维护一下就好了

尝试了一下循环展开并没有什么效果

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10;
const int mo=N*6;
int n,m,ph[N*4],pt[N*4],f[N*7],g[N*7],ans2[N];
int dy[50][35];
vector<int> ve[N*4];
#define rint register int
#define IL inline
char ss[1<<20],*A=ss,*B=ss;
IL char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<20,stdin),A==B)?EOF:*A++;}
template<class T> void read(T&x){
  rint f=1,c;
  while (c=gc(),c<48||57<c) 
    if (c=='-') f=-1;
  x=c^48;
  while (c=gc(),47<c&&c<58) x=(x<<3)+(x<<1)+(c^48);
  x*=f;
}
IL void insert(int x,int y)
{
  int xx=x%mo;
  while (f[xx]) xx++;
  f[xx]=x; g[xx]=y;
}
IL int find(int x)
{
  int xx=x%mo;
  while (f[xx]!=x) xx++;
  return(xx);
}
#define mid ((ph[x]+pt[x])/2)
void build(int x,int h,int t)
{
  ph[x]=h; pt[x]=t;
  if (h==t) return;
  build(x*2,h,mid); build(x*2+1,mid+1,t);
}
void insert2(int x,int h,int t,int k)
{
  if (h<=ph[x]&&pt[x]<=t)
  {
    ve[x].push_back(k);
    return;
  }
  if (h<=mid) insert2(x*2,h,t,k);
  if (mid<t) insert2(x*2+1,h,t,k);
}
void dfs(int x,int cnt)
{
  for (rint i=0;i<=30;i++) dy[cnt][i]=dy[cnt-1][i];
  rint len=ve[x].size();
  for (rint i=0;i<=len/4;i++)
  {
    
    if (i*4>=len) break;
    rint y1=ve[x][i*4],y2=ve[x][i*4+1],
         y3=ve[x][i*4+2],y4=ve[x][i*4+3];
    for (rint i1=30;i1>=0;i1--)
      if (y1&(1<<i1))
        if (!dy[cnt][i1])
        {
          dy[cnt][i1]=y1; break;
        } else y1^=dy[cnt][i1];
  
  
    if (i*4+1>=len) break;      
    for (rint i2=30;i2>=0;i2--)
      if (y2&(1<<i2))
        if (!dy[cnt][i2])
        {
          dy[cnt][i2]=y2; break;
        } else y2^=dy[cnt][i2];
  
  
    if (i*4+2>=len) break;
    for (rint i3=30;i3>=0;i3--)
      if (y3&(1<<i3))
        if (!dy[cnt][i3])
        {
          dy[cnt][i3]=y3; break;
        } else y3^=dy[cnt][i3];
  
  
    if (i*4+3>=len) break;    
    for (rint i4=30;i4>=0;i4--)
      if (y4&(1<<i4))
        if (!dy[cnt][i4])
        {
          dy[cnt][i4]=y4; break;
        } else y4^=dy[cnt][i4];
  }
  if (ph[x]==pt[x])
  {
    rint ans=0;
    for (rint i=30;i>=0;i--)
      if (dy[cnt][i]&&!(ans&(1<<i))) ans^=dy[cnt][i];
    ans2[ph[x]]=ans;
    return;
  }
  dfs(x*2,cnt+1); 
  dfs(x*2+1,cnt+1);
}
int main()
{
  freopen("4184.in","r",stdin);
  freopen("4184.out","w",stdout);
  read(n);
  build(1,1,n);
  for (int i=1;i<=n;i++)
  {
    int x;
    read(x);
    if (x<0)
    {
      int y=find(-x);
      insert2(1,g[y],i-1,-x);
      f[y]=0; g[y]=0;
    } else
    {
      insert(x,i);
    }
  }
  for (rint i=1;i<=N*7-10;i++)
    if (f[i])
    {
      insert2(1,g[i],n,f[i]);
    }
  dfs(1,1);
  for (int i=1;i<=n;i++)
    printf("%d\n",ans2[i]);
  return 0;
}

 

posted @ 2018-05-16 21:58  尹吴潇  阅读(253)  评论(0编辑  收藏  举报