zoukankan      html  css  js  c++  java
  • BZOJ3551 [ONTAK2010]Peaks加强版

    题目链接:戳我

    woc这题也太毒了吧。。。。卡空间要死啊???
    说一说怎么做——因为本题强制在线,所以用kruskal重构树,开始将边权从小到大排序,这样的话用最后一个新建的节点为根之后就是一个大根堆,所有边权小的都在节点的子树里。求K大——主席树。不过因为我们维护的是一棵树而不是序列,所以还要先dfs序一下。

    可惜蒟蒻码力不够,虽然看出来了怎么写但是还是不断锅锅锅,最后还是去参照了大佬的题解才过的这个题。。。。。

    bzoj上题面不是特别清楚。在这里补充一下——
    v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1则不变。
    这句话的意思是lastans是上一次询问的答案,如果上一次ans==-1,就不对v,x,k进行异或操作。开始lastans=0。
    然后题目让求的是第K大而非第K小(因为中国汉字意义博大精深,我看到第几大总是习惯性的先从小的想。。。。。告辞

    补一下正确的样例输入输出:
    输入:
    10 11 4

    1 2 3 4 5 6 7 8 9 10

    1 4 4

    2 5 3

    9 8 2

    7 8 10

    7 1 4

    6 7 1

    6 4 8

    2 1 5

    10 8 10

    3 4 7

    3 4 6

    1 5 2

    1 5 6

    1 5 8

    8 9 2
    输出:
    6
    10
    9
    -1

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define MAXN 200100
    using namespace std;
    int n,m,tot,edge_number,cnt,tt,num,lastans,q,kkk;
    int pre[MAXN],h[MAXN],head[MAXN],fa[MAXN],dis[MAXN];
    int ini[MAXN],rt[MAXN],dfn[MAXN],low[MAXN],f[MAXN][20];
    struct Edge{int nxt,to;}edge[MAXN<<1];
    struct Edge2{int u,v,w;}e[MAXN<<2];
    struct Node{int ls,rs,v;}t[MAXN<<5];
    inline void add(int from,int to)
    {
        edge[++edge_number].nxt=head[from];
        edge[edge_number].to=to;
        head[from]=edge_number;
    }
    inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    inline bool cmp(struct Edge2 x,struct Edge2 y){return x.w<y.w;}
    inline void dfs(int now,int ff)
    {
        //printf("now=%d ff=%d
    ",now,ff);
        if(now<=n) dfn[now]=low[now]=++tt,ini[tt]=now;
        else dfn[now]=(int)1e9,low[now]=0;
        f[now][0]=ff;
        for(int i=1;i<=19;i++)
            f[now][i]=f[f[now][i-1]][i-1];
        for(int i=head[now];i;i=edge[i].nxt)
        {
            dfs(edge[i].to,now);
            dfn[now]=min(dfn[now],dfn[edge[i].to]);
            low[now]=max(low[now],low[edge[i].to]);
        }
    }
    inline void modify(int &now,int ff,int l,int r,int pos)
    {
        now=++kkk;
        t[now]=t[ff],t[now].v++;
        //printf("now=%d ff=%d l=%d r=%d pos=%d
    ",now,ff,l,r,pos);
        if(l==r) return;
        int mid=(l+r)>>1;
        if(pos<=mid) modify(t[now].ls,t[ff].ls,l,mid,pos);
        else modify(t[now].rs,t[ff].rs,mid+1,r,pos);
    }
    inline int query(int now,int ff,int l,int r,int k)
    {
        if(l==r) return pre[l];
        int mid=(l+r)>>1;
        int cur_ans=t[t[ff].rs].v-t[t[now].rs].v;
        if(cur_ans>=k) query(t[now].rs,t[ff].rs,mid+1,r,k);
        else query(t[now].ls,t[ff].ls,l,mid,k-cur_ans);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin); 
        //freopen("ce.out","w",stdout);
        #endif
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=n;i++) 
            scanf("%d",&h[i]),pre[i]=h[i];
        sort(&pre[1],&pre[1+n]);
        cnt=unique(&pre[1],&pre[1+n])-pre-1;
        for(int i=1;i<=n;i++)
            h[i]=lower_bound(&pre[1],&pre[1+cnt],h[i])-pre;
        for(int i=1;i<=n;i++) 
            fa[i]=i;
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        sort(&e[1],&e[1+m],cmp);
        tot=n;
        for(int i=1;i<=m;i++)
        {
            int a=find(e[i].u),b=find(e[i].v);
            if(a==b) continue;
            ++tot;
            fa[tot]=fa[a]=fa[b]=tot;
            dis[tot]=e[i].w;
            add(tot,a),add(tot,b);
        }
        dfs(tot,0);
        for(int i=1;i<=n;i++)
            modify(rt[i],rt[i-1],1,cnt,h[ini[i]]);
        //for(int i=1;i<=n;i++) printf("rt[%d]=%d
    ",i,rt[i]);
        for(int i=1;i<=q;i++)
        {
            int v,x,k;
            scanf("%d%d%d",&v,&x,&k);
            if(lastans!=-1) v^=lastans,x^=lastans,k^=lastans;
            for(int i=19;i>=0;i--)
                if(f[v][i]&&dis[f[v][i]]<=x)
                    v=f[v][i];
            //printf("%d %d
    ",rt[dfn[v]-1],rt[low[v]]);
            if(low[v]-dfn[v]+1<k) lastans=-1;
            else lastans=query(rt[dfn[v]-1],rt[low[v]],1,cnt,k);
            printf("%d
    ",lastans);
        }
        return 0;   
    }
    

    不过有个问题是 从BZOJ上捞下来的数据为什么我自己在lemon上测是RE+TLE 放到BZOJ上竟然又跑过了????
    update:没开栈。。开了就过了

  • 相关阅读:
    Delphi集合的用法
    文字倒序输出(集合)
    如果知道两点的经纬度 如何算两点之间的距离
    Arcengine 开发完后,程序打包,在目标机器上不能使用 已解决
    arcengine License部署
    设置代理
    关于GPS坐标转换的学习笔记相当头疼
    ArcEngine 相关转载
    经纬度到平面坐标的相互转换
    用ArcEngine9.3开发GIS应用程序图层符号化解决方案
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10313767.html
Copyright © 2011-2022 走看看