F. 数学上来先打表

题解:

搞这题搞了一天

思维不是很难

就是暴力压位bitset

分块做法速度更快

但是stl里的不能实现这个功能

所以手动实现

64位压一位

到65535跑一下1的个数

然后(x>>16)&65535+...计算出1的个数

眼查错果然还是不靠谱以后还是写对拍吧

另外的难点在于这题很卡空间

我们建立dfs树

这样把总空间变为最大消耗空间

合并bitset的时候我们利用启发式合并

并且bitset只存出现了的位置

就是那些64位都没有出现的就不存了

空间是nlogn的,但是还是挺卡的吧

使用动态开数组的技巧替代vector

*int=calloc(大小,sizeof())

另外这个东西不会自动释放空间

所以我们要free()这个东西

代码:

 

#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define rint int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const int N=1.1e5;
struct bi{
  ull *v;
  int *pos,cnt;
  bi() { cnt=0;} 
}B[N];
int head[N],count2[N],count3[N],pos[N],pos2[N],pos3[N],pos4[N],fa[N],ans[N];
IL void js2(bi &a,bi b,int p)
{
  if (p==34319)
  {
    int sad;
    sad=0;
  }
    bi c;
    int tmp=a.cnt+b.cnt;
    c.v=(ull*)calloc(tmp+2,sizeof(ull));
    c.pos=(int*)calloc(tmp+2,sizeof(int));
    rint x=a.cnt,y=b.cnt;
    c.cnt=0;
    rint i=1,j=1;
    while (i<=x&&j<=y)
    {
      if (a.pos[i]<b.pos[j]) c.v[++c.cnt]=a.v[i],c.pos[c.cnt]=a.pos[i],i++;
      else if (a.pos[i]>b.pos[j]) c.v[++c.cnt]=b.v[j],c.pos[c.cnt]=b.pos[j],j++;
      else
      {
  //      if (a.v[i]^b.v[j])
        c.v[++c.cnt]=a.v[i]^b.v[j],c.pos[c.cnt]=b.pos[j]; 
        i++; j++;
      }
    }
    while (j<=y) c.v[++c.cnt]=b.v[j],c.pos[c.cnt]=b.pos[j],j++;
    while (i<=x) c.v[++c.cnt]=a.v[i],c.pos[c.cnt]=a.pos[i],i++;
    free(a.v); free(a.pos);
    a=c;
}
struct re{
  int a,b,c,d;
}e[N*2],a[N];
bool cmp(re x,re y)
{
  return(x.a<y.a);
}
int l;
void arr(int x,int y,int x1,int y1)
{
  e[++l].a=head[x];
  e[l].b=y;
  e[l].c=x1;
  e[l].d=y1;
  head[x]=l;
}
#define js(x) (count2[x&65535]+count2[(x>>16)&65535]+count2[(x>>32)&65535]+count2[(x>>48)&65535])
int find(int x)
{
  return fa[x]==x?x:find(fa[x]);
}
vector<re> ve[N];
void dfs(int x)
{
  int l=(int)(ve[x].size())-1;
    rep(i,0,l)
    {
      int x1=pos4[find(ve[x][i].a)],x2=ve[x][i].b,x3=ve[x][i].c;
      int cnt=0;
      rep(i,1,B[x1].cnt)
        if (cnt+js(B[x1].v[i])<x2)
          cnt+=js(B[x1].v[i]);
        else
        {
          ull o=B[x1].v[i];
          rep(j,0,63) 
            if ((o>>j)&1)
            { 
              cnt++;
              if (cnt==x2)
              { 
                ans[x3]=64*(B[x1].pos[i]-1)+j+1; break;
              }
            }
          break;
        }
      if (cnt<x2) ans[x3]=-1;
    }
  for (rint u=head[x];u;u=e[u].a)
  {
    rint v=e[u].b;
    rint x1=find(e[u].c),x2=find(e[u].d),tmp=0;
  //  bi tmp2;
    bool tt=0;
    if (x1!=x2)
    {
      tt=1;
      if (count3[x1]>count3[x2]) swap(x1,x2);
      fa[x1]=x2; count3[x2]+=count3[x1];
      int k1=B[pos4[x1]].cnt,k2=B[pos4[x2]].cnt;
      if (k1>k2)
      { 
        tmp=pos4[x2];
      //  tmp2=B[pos4[x1]];
        js2(B[pos4[x1]],B[pos4[x2]],1);
        pos4[x2]=pos4[x1]; 
      } else 
      js2(B[pos4[x2]],B[pos4[x1]],pos4[x2]);
    }
    dfs(v);
    if (tt)
    {
      fa[x1]=x1; count3[x2]-=count3[x1];
      if (tmp)
      {
        pos4[x2]=tmp; js2(B[pos4[x1]],B[tmp],1);
      } else 
      {
        js2(B[pos4[x2]],B[pos4[x1]],pos4[x2]);
      }
    }
  }
}
int main()
{
  ios::sync_with_stdio(false);
  rep(i,0,65536) count2[i]=count2[i>>1]+(i&1);
  int n,m;
  cin>>n>>m;
  rep(i,1,n) cin>>a[i].a,a[i].b=i;
  rep(i,1,n) pos4[i]=i,count3[i]=1;
  sort(a+1,a+n+1,cmp);
  rep(i,1,n) pos[a[i].b]=i,pos2[i]=a[i].a;
  rep(i,1,n)
  {
    B[i].v=(ull*)calloc(2,sizeof(ull)); B[i].pos=(int*)calloc(2,sizeof(int));
    int t=pos[i]; t--;
    B[i].pos[1]=(t/64)+1; B[i].v[1]=1ull<<(t%64);
    fa[i]=i;
    B[i].cnt=1;
  }
  int now,cnt,cnt2=0;
  now=cnt=1;
  pos3[0]=1;
  rep(i,1,m)
  {
    int kk,x,y;
    cin>>kk;
    if (kk==1)
    {
      cin>>x>>y;
      arr(now,++cnt,x,y);
      pos3[i]=cnt;
      now=cnt;
    }
    if (kk==2)
    {
      cin>>x;
      now=pos3[x];
    }
    if (kk==3)
    {
      cin>>x>>y;
      ve[now].push_back((re){x,y,++cnt2});
    }
    pos3[i]=now;
  }
  dfs(1);
  rep(i,1,cnt2) 
  if (ans[i]==-1) cout<<-1<<endl;
  else cout<<pos2[ans[i]]<<endl;
  return 0;
}

 

posted @ 2018-08-22 16:25  尹吴潇  阅读(186)  评论(0编辑  收藏  举报