zoukankan      html  css  js  c++  java
  • 【Peaks加强版 BZOJ 3551】你被坑了吗?

    这道在没加读入优化时间在20s左右的题终于在大米饼两天的死缠烂打、鬼混、乱整乱撞后艰难地AC了。但惋惜的是,大米饼一号代码其实更加简洁,但至今找不出BUG,我将它放在下面,也许有一天从远方来的另一个大米饼会拯救它。让我们一起念出这道题的关键字:

    Kurskal,LCA倍增,Kurskal重构树,dfs序,主席树。

    比较新鲜的是重构树,它有一些美妙性质。

    【库尔斯卡重构树】

    红色的是由边化成的节点。用Kurskal建出这棵树,在这一棵树上进行DFS序处理,并且在DFS序上进行主席树(可持久化线段树)处理。有趣的是,这道题读入优化可以加速5s,是不是很美妙!

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define ro(i,a,b) for(int i=a;i>=b;i--)
     5 #define go(i,a,b) for(int i=a;i<=b;i++)
     6 using namespace std;
     7 const int inf=2147483646;const int logp=18;const int N=1e5+233;
     8 const int M=5e5+233;const int P=N<<1;const int E=P<<1;const int S=P*logp ;
     9 int n,m,q,p,num,cnt,K,d[N],h[N],dad[P],val[P],rt[P],lc[S],rc[S],sum[S];
    10 int si[P],dep[P],dfn[P],pos[P],head[P],nex[E],ver[E],fa[logp+1][P],pr[logp+1],lg[P];
    11 struct edge{int x,y,z;};edge a[M];
    12 bool cmp(edge a, edge b){return a.z<b.z;}
    13 int find(int x){return dad[x]!=x?dad[x]=find(dad[x]):x;}
    14 void ADD(int u, int v){nex[++K]=head[u];head[u]=K;ver[K]=v;}
    15 void dfs(int u)
    16 {
    17     si[u]=1;dfn[u]=++num;pos[num]=u;
    18     for(int i=head[u];i;i=nex[i])
    19     {int v=ver[i];fa[0][v]=u;dep[v]=dep[u]+1;dfs(v);si[u]+=si[v];}
    20 }
    21 void Kruskal()
    22 {
    23     p=n;sort(a+1,a+1+m,cmp);
    24     go(i,1,m){int x=find(a[i].x),y=find(a[i].y);
    25     if(x!=y){dad[++p]=p;val[p]=a[i].z;dad[x]=dad[y]=p;
    26     ADD(p,x),ADD(p,y);if(p==(n<<1)-1)break;}}
    27 }
    28 void Rmq()
    29 {
    30     go(k,1,lg[p])go(i,1,p){if(dep[i]<pr[k])continue;
    31     fa[k][i]=fa[k-1][fa[k-1][i]];}
    32 }
    33 int Add(int p,int l,int r,int x)
    34 {
    35     int k=++cnt;sum[k]=sum[p]+1;if(l==r)return k;int mid=l+r>>1;
    36     if(x<=mid)lc[k]=Add(lc[p],l,mid,x),rc[k]=rc[p];
    37     else rc[k]=Add(rc[p],mid+1,r,x),lc[k]=lc[p];return k;
    38 }
    39 void prepare()
    40 {
    41     Kruskal();num=0;go(i,1,p)if(!dfn[i])dfs(find(i));pr[0]=1;
    42     go(i,1,logp){pr[i]=pr[i-1]<<1;if(pr[i]>p)break;lg[pr[i]]=1;}
    43     go(i,1,p)lg[i]+=lg[i-1];Rmq();go(i,1,num)
    44     {int x=pos[i];if(x>n)rt[i]=rt[i-1];else rt[i]=Add(rt[i-1],1,n,h[x]);}
    45 }
    46 int Jump(int x, int v){
    47     int len=lg[dep[x]];ro(i,len,0)if(val[fa[i][x]]<=v)x=fa[i][x];return x;
    48 }
    49 int Query(int a, int b, int l, int r, int k)
    50 {
    51     if(l==r)return l;int amo=sum[rc[b]]-sum[rc[a]];
    52     int mi=l+r>>1;if(amo<k)return Query(lc[a],lc[b],l,mi,k-amo);
    53     return Query(rc[a],rc[b],mi+1,r,k);
    54 }
    55 int Ask(int x, int v, int k)
    56 {
    57     int anc=Jump(x,v),beg=rt[dfn[anc]-1],end=rt[dfn[anc]+si[anc]-1];
    58     if(sum[end]-sum[beg]<k)return -1;
    59     int hi=Query(beg,end,1,n,k);return d[hi];
    60 }
    61 int main()
    62 {
    63     scanf("%d%d%d",&n,&m,&q);val[0]=inf;
    64     go(i,1,n)scanf("%d",&h[i]),d[i]=h[i],dad[i]=i;
    65     sort(d+1,d+1+n);go(i,1,n)h[i]=lower_bound(d+1,d+1+n,h[i])-d;
    66     go(i,1,m)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    67     prepare();int ans=-1;while(q--)
    68     {
    69         int x,v,k;scanf("%d%d%d",&x,&v,&k);
    70         if(ans != -1)x^=ans,v^=ans,k^=ans;
    71         ans=Ask(x,v,k);printf("%d
    ",ans);
    72     }
    73 }
    【大米饼代码】

    下面是暂时RE的代码:

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #define go(i,a,b) for(int i=a;i<=b;i++)
     4 #define ro(i,a,b) for(int i=a;i>=b;i--)
     5 #define rule 1000000000
     6 using namespace std;const int N=100003;struct TT{int siz,l,r;}t[N*20];
     7 struct G{int u,v,w;bool operator<(const G&X)const{return w<X.w;};}g[N*20];
     8 int n,m,q,fa[N],ch[N][2],SZ,sz,val[N],root,v,x,k,ans=0,T[N];
     9 int up[N][20],dis[N][20],start[N],end[N],dfs_clock,DFS[N],ROOT[N];
    10 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    11 int get_root(int x,int val){ro(j,19,0)if(up[x][j]&&dis[x][j]<=val)x=up[x][j];return x;} 
    12 void dfs(int u){if(!u)return;start[u]=dfs_clock;
    13     if(ch[u][1]+ch[u][0]<1)DFS[++dfs_clock]=val[u];
    14     go(i,0,1)dfs(ch[u][i]);end[u]=dfs_clock;
    15 }
    16 void insert(int& x,int Val,int l,int r){
    17     t[++sz]=t[x];x=sz;++t[x].siz;if(l==r)return;
    18     int mid=(l+r)/2;if(Val<=mid)insert(t[x].l,Val,l,mid);
    19     else insert(t[x].r,Val,mid+1,r);
    20 }
    21 void Que(int i,int j,int k,int l,int r){
    22     if( l==r ){ans=l;return;}
    23     int tmp=t[t[j].l].siz-t[t[i].l].siz,mid=(r+l)/2;
    24     if(k<=tmp)Que(t[i].l,t[j].l,k,l,mid);else Que(t[i].r,t[j].r,k-tmp,mid+1,r);
    25 }
    26 int main(){
    27     freopen("in.in","r",stdin);
    28     scanf("%d%d%d",&n,&m,&q);SZ=n;
    29     go(i,1,n)scanf("%d",&val[i]),fa[i]=i;
    30     go(i,1,m)scanf("%d%d%d",&g[i].u,&g[i].v,&g[i].w);
    31     sort(g+1,g+m+1);int tot=n;go(i,1,m)
    32     {
    33         int Fa=find(g[i].u),Fb=find(g[i].v);
    34         if(Fa==Fb)continue;if(!--tot)break;
    35         int u=++SZ;fa[u]=fa[Fa]=fa[Fb]=u;
    36         ch[u][0]=Fa,ch[u][1]=Fb;
    37         up[Fa][0]=up[Fb][0]=u;
    38         dis[Fa][0]=dis[Fb][0]=g[i].w;
    39     }
    40     
    41     dfs(SZ);go(i,1,n)ROOT[i]=ROOT[i-1],insert(ROOT[i],DFS[i],0,rule);  
    42     go(j,1,19)go(i,1,SZ)up[i][j]=up[up[i][j-1]][j-1],  
    43     dis[i][j]=max(dis[i][j-1],dis[up[i][j-1]][j-1]); 
    44      
    45     go(i,1,q)  
    46     {  
    47         scanf("%d%d%d",&v,&x,&k);x^=ans;v^=ans;k^=ans;
    48         root=get_root(x,v);
    49         int gap=end[root]-start[root];
    50         if(gap<k){puts("-1");ans=0;continue;}  
    51         Que(ROOT[start[root]],ROOT[end[root]],gap-k+1,0,rule);  
    52         if(!ans){puts("-1");ans=0;continue;}printf("%d
    ",ans);  
    53     } 
    54     return 0;
    55 }//Paul_Guderian
    【大米饼一号代码】

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    你没有达到顶尖!但记得给我买杯柠檬汁。

  • 相关阅读:
    【crontab】误删crontab及其恢复
    New Concept English there (7)
    New Concept English there (6)
    New Concept English there (5)
    New Concept English there (4)
    New Concept English there (3)
    New Concept English there (2)Typing speed exercise
    New Concept English there (1)Typing speed exercise
    New Concept English Two 34 game over
    New Concept English Two 33 94
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/6653765.html
Copyright © 2011-2022 走看看