zoukankan      html  css  js  c++  java
  • 【BZOJ3307】雨天的尾巴

    题解:

    win下的10mb和linux下的好像不是很一样 明天再看看

    求lca用的离线求,注意bz数组开2*n

    这道题的线段树合并还是很好想的

    我们只要把操作差分一下就好了

    时间复杂度nlogn的

    写代码用时:1:30

    对拍+maker+调错=30

    看到网上题解用的是树剖。。

    我看了很久很久才理解。。

    以前我用树剖都没有去理解它变成序列这个本质。。

    树剖保证了区间的连续性,所以差分对于不在同一段的完全没有影响

    所以树剖完了就直接变成序列问题,非常强势啊

    明天补

    这样是nlognlogn的

    正解:

    #include <bits/stdc++.h>
    using namespace std;
    #define IL inline
    #define rint register int
    const int N=1.1e5;
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<24,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 maxa(int &x,int y)
      {
        if (x>y) return;
        else x=y;
      } 
      IL void mina(int &x,int y)
      {
        if (x<y) return;
        else x=y;
      }
      IL int max(int x,int y)
      {
         if (x>y) return(x); else return(y);
      }
      IL int min(int x,int y)
      {
         if (x<y) return(x); else return(y); 
      }
    int n,m,fa[N],head[N],fi[N],root[N],cnt,cnt2,l,ans[N];
    struct re{
      int a,b;
    }a[N*2],b[N],c[N];
    IL void arr(int x,int y)
    {
      a[++l].a=head[x];
      a[l].b=y;
      head[x]=l;
    }
    int id[N],dy[N],bz[21][N*2],pos[N],vt[N],fdy[N];
    vector <int> ve1[N],ve2[N];
    void dfs(int x)
    {
      id[x]=++cnt;
      dy[cnt]=x;
      bz[0][++cnt2]=id[x];
      pos[x]=cnt2;
      int u=head[x];
      while (u)
      {
        int v=a[u].b;
        if (v!=fa[x])
        {
          fa[v]=x;
          dfs(v);
          bz[0][++cnt2]=id[x];
        }
        u=a[u].a;
      }
    }
    IL void swap(int &x,int &y)
    {
      int z=x; x=y; y=z;
    }
    IL int lca(int x,int y)
    {
      if (x==y) return(x);
      x=pos[x],y=pos[y];
      if (x>y) swap(x,y);
      int z=log2(y-x+1);
      return(dy[min(bz[z][x],bz[z][y-(1<<z)+1])]);
    }
    struct segementree
    {
      int cnt;
      int v[N*20],p[N*20],ls[N*20],rs[N*20];
      segementree() { cnt=0; }
      #define mid ((h+t)/2)
      IL void updata(int x)
      {
         v[x]=max(v[ls[x]],v[rs[x]]);
         if (v[ls[x]]>v[rs[x]]||(v[ls[x]]==v[rs[x]]&&p[ls[x]]<p[rs[x]]))
            p[x]=p[ls[x]];
         else p[x]=p[rs[x]];
      }
      void change(int &x,int h,int t,int pos,int k)
      {
        if (!x) x=++cnt;
        if (h==t)
        { 
          v[x]+=k; p[x]=pos; return;
        }
        if (pos<=mid) change(ls[x],h,mid,pos,k);
        else change(rs[x],mid+1,t,pos,k);
        updata(x);
      }
      int merge(int x,int y,int h,int t)
      {
        if (!x||!y) return(x^y);
        ls[x]=merge(ls[x],ls[y],h,mid);
        rs[x]=merge(rs[x],rs[y],mid+1,t);
        if (h==t) v[x]+=v[y];
        else updata(x);
        return(x);
      }
    }se1;
    void dfs2(int x)
    {
      rint u=head[x];
      while (u)
      {
        rint v=a[u].b;
        if(v!=fa[x])
        {
          dfs2(v);
          root[x]=se1.merge(root[x],root[v],1,m);
        }
        u=a[u].a;
      }
      for (rint i=0;i<ve1[x].size();i++)
        se1.change(root[x],1,m,ve1[x][i],1);
      for (rint i=0;i<ve2[x].size();i++)
        se1.change(root[x],1,m,ve2[x][i],-1);
      if(!se1.v[root[x]]) ans[x]=0;
      else ans[x]=se1.p[root[x]];
    }
    IL bool cmp(re x,re y)
    {
      return(x.a<y.a);
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      read(n); read(m); 
      int x,y;
      for (int i=1;i<=n-1;i++)
      {
        read(x); read(y); arr(x,y); arr(y,x); 
      }
      dfs(1);
      for (rint i=1;i<=20;i++)  
        for (rint j=1;j<=cnt2;j++)
          if ((1<<(i-1))+j-1<=cnt2)
            bz[i][j]=min(bz[i-1][j],bz[i-1][j+(1<<(i-1))]);
      for( int i=1;i<=m;i++)
      {
        read(c[i].a); read(c[i].b);
        read(b[i].a); b[i].b=i; 
      }
      sort(b+1,b+m+1,cmp);
      b[0].a=1e9;
      int cnt3=0;
      for (int i=1;i<=m;i++)
      {
        if (b[i].a!=b[i-1].a)
        {
          cnt3++;
          fdy[cnt3]=b[i].a;
        }
        vt[b[i].b]=cnt3;
      }
      for (int i=1;i<=m;i++)
      {
        int x=c[i].a,y=c[i].b,z=vt[i];
        // cout<<x<<" "<<y<<" "<<z<<" "; 
        int xx=lca(x,y);
        //cout<<xx<<endl;
        ve1[x].push_back(z);
        ve1[y].push_back(z);
        ve2[xx].push_back(z);
        ve2[fa[xx]].push_back(z);
      }
      dfs2(1);
      for (int i=1;i<=n;i++) 
      {
        printf("%d
    ",fdy[ans[i]]);
      }
      return 0; 
    }
    //离散化 

    拍:

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e3;
    int v[N][N];
    int head[N],n,m,l;
    struct re{
      int a,b;
    }a[N*2];
    void arr(int x,int y)
    {
      a[++l].a=head[x];
      a[l].b=y;
      head[x]=l;
    }
    int cnt=0,id[N],dy[N],fa[N];
    void dfs(int x,int fa1)
    {
      int u=head[x];
      id[x]=++cnt;
      dy[cnt]=x;
      while (u)
      {
        int v=a[u].b;
        if (v!=fa1) fa[v]=x,dfs(v,x);
        u=a[u].a;
      }
    }
    const int INF=1e9;
    bool pd(int x,int y)
    {
      while (x!=y&&x) x=fa[x];
      if(x==y) return(1); else return(0);
    }
    int lca(int x,int y)
    {
      int ans=0;
      for (int i=1;i<=n;i++)
        if (pd(x,i)&&pd(y,i)) ans=max(ans,id[i]);
      return(dy[ans]);
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("2.out","w",stdout);
      cin>>n>>m;
      for (int i=1;i<=n-1;i++)
      {
        int x,y;
        cin>>x>>y;
        arr(x,y); arr(y,x);
      }
      dfs(1,0);
      for (int i=1;i<=m;i++)
      {
        int x,y,z;
        cin>>x>>y>>z;
        int xx=lca(x,y);
        for (int i=x;i!=fa[xx];i=fa[i]) v[i][z]++;
        for (int i=y;i!=fa[xx];i=fa[i]) v[i][z]++;
        v[xx][z]--;
      }
      for (int i=1;i<=n;i++)
      {
        int ans=0,ans2=0;
        for (int j=1;j<=100;j++)
          if(v[i][j]>ans) ans=v[i][j],ans2=j;
        cout<<ans2<<endl;
      }
      return 0;
    } 

    数据:

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
      freopen("1.in","w",stdout);
      int n=100000,m=100000;
      cout<<n<<" "<<m<<endl;
      srand(time(0));
      for (int i=2;i<=n;i++)
      {
        int x=rand()%(i-1)+1;
        cout<<x<<" "<<i<<endl; 
      }
      for (int i=1;i<=m;i++)
      {
        int x=rand()%n+1,y=rand()%n+1,z=rand()%1000000000+1;
        cout<<x<<" "<<y<<" "<<z<<endl; 
      }
    }
  • 相关阅读:
    eclipse fail to create java virtual machine
    sas软件连接Oracle数据库的办法
    JAVA中数据的读取与写入,不同类型数据的转换
    二维数组的在函数中的传递
    【转】值传递与引用传递
    【转】深拷贝与浅拷贝
    (转)JS报表控件highcharts应用
    highstocks.js使用指南
    (转)Highcharts使用指南(出处:http://liuhaorain.cnblogs.com )
    jQuery实现checkbox全选,反选
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9065331.html
Copyright © 2011-2022 走看看