zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    雅虎网站页面性能优化的34条黄金守则
    borderimage
    jQuery实现滚动加载图片效果
    mysql数据库中创建与删除数据表
    (10)一步一步开发一个简单CAD之捕捉
    apach启动失败的原因
    (12)一步一步开发一个简单CAD之观察者模式
    简单基于OPENGL的三维CAD框架(1)照相机类
    简单基于OPENGL的三维CAD框架(1)COpenGLDC
    (13)一步一步开发一个简单CAD之像皮筋类
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9518485.html
Copyright © 2011-2022 走看看