zoukankan      html  css  js  c++  java
  • bzoj3551

    3551: [ONTAK2010]Peaks加强版

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 877  Solved: 297
    [Submit][Status][Discuss]

    Description

    【题目描述】同3545

    Input

    第一行三个数N,M,Q。
    第二行N个数,第i个数为h_i
    接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
    接下来Q行,每行三个数v x k,表示一组询问。v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1则不变。
     

    Output

    同3545

    Sample Input

     

    Sample Output

     

    HINT

    【数据范围】同3545

    Source

    题解:

      过了这么久才又开始写博客(省选被虐成渣,现在还要准备半期考试 only shit)好吧,算了毕竟太渣,不多说了,写题解QAQ

      看了题目,一脸懵逼,怎么写?(不会) 怎么办?(看题解)

      首先看看这道题,它是一个无向图,根本不知道怎么来写主席树,操蛋。

      仔细看看题,我们可以这样想,我要走一个边权比x小的边,并且一直走下去,我们不就可以用最小生成树吗?每次走最小的边,那么一定是最优的,所以我们就用kruskal来写

      但是要注意的是,在找到一个新的边时,新建一个节点,权值为边的权值,把边的两端连向这个点,不难证明这是一课树。。。。。

      然后每次询问就从当前点往上面倍增地跳,直到不能走(点权大于x) 那么那个点的子树中的点就是我可以到达的点

      于是题目就变成求一个子树第k大的问题。。。用lca加和主席树就A了

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define maxn 300005
      7 #define maxnode 2000005
      8 using namespace std;
      9 int n,m,q,lastans,top;
     10 int size,tot,ext;
     11 int pre[maxn],now[maxn],v[maxn],fa[maxn],sum[maxnode],son[maxnode][2],pp[maxn];
     12 int bin[20],deep[maxn],f[maxn][20],mx[maxn][20];
     13 int h[maxn],list[maxn],qz[maxn],root[maxn],st[maxn],ed[maxn];
     14 bool vis[maxn];
     15 struct date{int u,v,val;
     16 }a[500005];
     17 int read()
     18 {
     19     int x=0; char ch; bool bo=0;
     20     while (ch=getchar(),ch<'0'||ch>'9') if (bo=='-') bo=1;
     21     while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
     22     if (bo) return -x; return x;
     23 }
     24 bool cmp_val(date a, date b)
     25 {
     26     return a.val<b.val;
     27 }
     28 int find(int x)
     29 {
     30     if (fa[x]!=x) fa[x]=find(fa[x]);
     31     return fa[x];
     32 }
     33 void insert(int x,int y){tot++; pre[tot]=now[x]; now[x]=tot; v[tot]=y;
     34 }
     35 void ins(int l,int r,int x,int &y,int val)
     36 {
     37     int t;
     38     if (!y) y=++tot; sum[y]=sum[x]+1;
     39     if (l==r) return;
     40     int mid=(l+r)>>1;
     41     if (val<=mid) t=0,r=mid; else t=1,l=mid+1;
     42     son[y][t^1]=son[x][t^1];
     43     ins(l,r,son[x][t],son[y][t],val);
     44 }
     45 void dfs(int x)
     46 {
     47     vis[x]=1; pp[++top]=x;
     48     for (int i=1; i<=16; i++)
     49         if (bin[i]<=deep[x])
     50         {
     51             f[x][i]=f[f[x][i-1]][i-1];
     52             mx[x][i]=max(mx[x][i-1],mx[f[x][i-1]][i-1]);
     53         }
     54     for (int p=now[x]; p; p=pre[p])
     55     {
     56         int son=v[p];
     57         deep[son]=deep[x]+1;
     58         f[son][0]=x;
     59         mx[son][0]=qz[x];
     60         dfs(son);
     61     }
     62     if (x>n) pp[++top]=x;
     63 }
     64 void build()
     65 {
     66     ext=n;
     67     sort(a+1,a+m+1,cmp_val);
     68     for (int i=1; i<=m; i++)
     69     {
     70         int q=find(a[i].u),p=find(a[i].v);
     71         if (q!=p)
     72         {
     73             ext++;
     74             fa[q]=fa[p]=ext; qz[ext]=a[i].val;
     75             insert(ext,p);  insert(ext,q); 
     76             if (ext==2*n-1) break;
     77         }
     78     }
     79     for (int i=1; i<=n; i++)
     80     {
     81         if (!vis[i]) dfs(find(i));
     82     }
     83     for (int i=1; i<=top; i++)
     84     {
     85         int t=pp[i];
     86         if (t<=n) ins(1,n,root[i-1],root[i],h[t]);
     87         else
     88         {
     89             root[i]=root[i-1];
     90             if (!st[t]) st[t]=i; else ed[t]=i;
     91         }
     92     }
     93 }
     94 int valfind(int x,int val)
     95 {
     96     for(int i=17;i>=0;i--)
     97         if(deep[x]>=bin[i]&&mx[x][i]<=val)x=f[x][i];
     98     return x;
     99 }
    100 int query(int l,int r,int x,int y,int val)
    101 {
    102     if (l==r) return l;
    103     int mid=(l+r)>>1;
    104     int kk=sum[son[y][0]]-sum[son[x][0]],t;
    105     //cout<<"         "<<kk<<endl;
    106     if (kk>=val) return query(l,mid,son[x][0],son[y][0],val);
    107     else return query(mid+1,r,son[x][1],son[y][1],val-kk);
    108 }
    109 void solve()
    110 {
    111     while (q--)
    112     {
    113         int x=read(),val=read(),k=read();
    114         if (lastans!=-1) x^=lastans,val^=lastans,k^=lastans;
    115         int t=valfind(x,val);
    116         int a=root[st[t]],b=root[ed[t]];
    117         if (sum[b]-sum[a]<k) lastans=-1;
    118         else lastans=list[query(1,n,a,b,sum[b]-sum[a]-k+1)];
    119         printf("%d
    ",lastans);
    120     }
    121      
    122 }
    123 void prework()
    124 {
    125     bin[0]=1;
    126     for (int i=1; i<20; i++) bin[i]=bin[i-1]<<1;
    127     for (int i=1; i<=2*n; i++) fa[i]=i;
    128     sort(list+1,list+1+n);
    129     for (int i=1; i<=n; i++) h[i]=lower_bound(list+1,list+1+n,h[i])-list;
    130     for (int i=1; i<=m; i++)
    131     {
    132         a[i].u=read(); a[i].v=read(); a[i].val=read();
    133     }
    134     build();
    135 }
    136 int main()
    137 {
    138     n=read(); m=read(); q=read();
    139     for (int i=1; i<=n; i++) list[i]=h[i]=read();
    140     prework();
    141     solve();
    142     return 0;
    143 } 
    View Code

      

  • 相关阅读:
    kaggle之员工离职分析
    Titanic幸存预测分析(Kaggle)
    学习python,第五篇
    VLAN入门知识
    复习下VLAN的知识
    复习下网络七层协议
    学习python,第四篇:Python 3中bytes/string的区别
    学习python,第三篇:.pyc是个什么鬼?
    学习python,第二篇
    学习python,第一篇
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5444295.html
Copyright © 2011-2022 走看看