zoukankan      html  css  js  c++  java
  • BZOJ 3166 HEOI2013 ALO 可持久化trie+st表

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3166(洛谷上也有)

    题意概述:

      给出一个序列,对于一个区间,其权值为区间中的次大值亦或区间中任意一个数的结果的最大值。求区间权值的最大值。

    分析:

      考虑每个点作为区间次大的状态,发现对于每个点至多有两个最长区间其为次大值(为了让异或结果最大当然是区间越长越好,选择最多),用二分+静态RMQ算出这两个区间再在可持久化trie上面贪心即可。

      论如何现场yy可持久化数据结构23333(基于可持久化线段树的yy算法)

      注意一下算区间的边界问题。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<set>
      9 #include<map>
     10 #include<vector>
     11 #include<cctype>
     12 using namespace std;
     13 const int MAXN=50005;
     14 
     15 int N,a[MAXN];
     16 struct data{ int l,r,v; }q[MAXN<<1]; int cnt;
     17 int mx[MAXN][18];
     18 struct Trie{
     19     static const int maxn=1600000;
     20     static const int maxm=50005;
     21     int np,root[maxm],to[maxn][2],sum[maxn];
     22     Trie(){ np=sum[0]=0; memset(to[0],0,sizeof(to[0])); }
     23     int copynode(int p){
     24         memcpy(to[++np],to[p],sizeof(to[p]));
     25         sum[np]=sum[p];
     26         return np;
     27     }
     28     void ins(int ver,int x){
     29         root[ver]=copynode(root[ver-1]);
     30         int p=root[ver],d;
     31         for(int i=30;i>=0;i--){
     32             sum[p]++,d=(x>>i)&1;
     33             if(!to[p][d]){
     34                 to[p][d]=++np,sum[np]=0;
     35                 memset(to[np],0,sizeof(to[np]));
     36                 p=to[p][d];
     37             }
     38             else to[p][d]=copynode(to[p][d]),p=to[p][d];
     39         }
     40         sum[p]++;
     41     }
     42     int query(int A,int B,int w){
     43         int p1=root[A],p2=root[B],d;
     44         for(int i=30;i>=0;i--){
     45             d=((w>>i)&1)^1;
     46             if(sum[to[p2][d]]-sum[to[p1][d]])
     47                 p1=to[p1][d],p2=to[p2][d],w^=d<<i;
     48             else p1=to[p1][d^1],p2=to[p2][d^1],w^=1-d<<i;
     49         }
     50         return w;
     51     }
     52 }trie;
     53 
     54 void _scanf(int &x)
     55 {
     56     x=0;
     57     char c=getchar();
     58     while(c<'0'||c>'9') c=getchar();
     59     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     60 }
     61 void data_in()
     62 {
     63     _scanf(N);
     64     for(int i=1;i<=N;i++) _scanf(a[i]);
     65 }
     66 void get_st()
     67 {
     68     for(int i=1;i<=N;i++) mx[i][0]=a[i];
     69     for(int i=N;i>=1;i--)
     70     for(int j=1;(1<<j)<=N-i+1;j++)
     71         mx[i][j]=max(mx[i][j-1],mx[i+(1<<j-1)][j-1]);
     72 }
     73 int query(int x,int y)
     74 {
     75     int k=0;
     76     while((1<<k+1)<y-x+1) k++;
     77     return max(mx[x][k],mx[y-(1<<k)+1][k]);
     78 }
     79 int getp1(int p,int v)
     80 {
     81     int re=p,mid,L=1,R=p;
     82     while(L<R){
     83         mid=L+R>>1;
     84         if(query(mid,p-1)>v) L=mid+1;
     85         else R=mid,re=mid;
     86     }
     87     return re;
     88 }
     89 int getp2(int p,int v)
     90 {
     91     int re=p,mid,L=p+1,R=N+1;
     92     while(L<R){
     93         mid=L+R>>1;
     94         if(query(p+1,mid)>v) R=mid;
     95         else L=mid+1,re=mid;
     96     }
     97     return re;
     98 }
     99 void work()
    100 {
    101     get_st();
    102     for(int i=1;i<=N;i++){
    103         int p1=getp1(i,a[i]),p2=getp2(i,a[i]);
    104         if(p1>1) q[++cnt]=(data){getp1(p1-1,a[i]),p2,a[i]};
    105         if(p2<N) q[++cnt]=(data){p1,getp2(p2+1,a[i]),a[i]};
    106     }
    107     for(int i=1;i<=N;i++) trie.ins(i,a[i]);
    108     int ans=0;
    109     for(int i=1;i<=cnt;i++)
    110         ans=max(ans,trie.query(q[i].l-1,q[i].r,q[i].v));
    111     printf("%d
    ",ans);
    112 }
    113 int main()
    114 {
    115     data_in();
    116     work(); 
    117     return 0;
    118 }
  • 相关阅读:
    后台线程处理数据,如何实时更新UI(datagridview)多线程同步问题
    DataGridView设置行高
    C#打开外部文件,如txt文件
    20120621第一天_复习与测试\04continue
    关于C#正则表达式MatchCollection类的总结
    关于sqlite中的一个错误 “database is locked"
    UI中 加个timer 写个while true的方法 不断获取run的对象
    最近帮公司开发一个邮件营销软件 用到XPTable 但找了很多方法 摸索了很久都不知道如何更新进度条 不过在国外的一个网站 终于找到答案了
    C# 简单的往txt中写日志,调试时很有用 【转】
    输入要匹配的内容和正则表达式规则 返来单个匹配的内容 正则表达式方法 常用
  • 原文地址:https://www.cnblogs.com/KKKorange/p/8728091.html
Copyright © 2011-2022 走看看