• [BZOJ4358]permu


    题目大意:
      $P$为$1sim n(nleq50000)$的一个排列。给出$m(mleq50000)$个询问,每次询问区间$[l,r]$中,最长值域连续段长度。

    思路:
      莫队+线段树。线段树上维护区间最长值域连续段长度、与区间左端点相连的最长值域连续段长度和与区间右端点相连的最长值域连续段长度。时间复杂度$O(nsqrt nlog n)$。
      然后就TLE了,看了题解才知道标算原来是$O(nsqrt n)$的莫队+栈或者KD树,然而也看到不少线段树卡常A掉的,不过我怎么卡常都A不掉,好像是BZOJ更新后卡时更准了。最后在DBZOJ上交了一发,只跑了8000ms。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<sys/mman.h>
     4 #include<sys/stat.h>
     5 class BufferedInputStream {
     6     private:
     7         char *buf,*p;
     8         int size;
     9     public:
    10         BufferedInputStream() {
    11             register int fd=fileno(stdin);
    12             struct stat sb;
    13             fstat(fd,&sb);
    14             size=sb.st_size;
    15             p=buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0));
    16         }
    17         char getchar() {
    18             return (p==buf+size||*p==EOF)?EOF:*p++;
    19         }
    20 };
    21 BufferedInputStream in;
    22 inline int getint() {
    23     register char ch;
    24     while(!__builtin_isdigit(ch=in.getchar()));
    25     register int x=ch^'0';
    26     while(__builtin_isdigit(ch=in.getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    27     return x;
    28 }
    29 const int N=50001,M=50000;
    30 int p[N],ans[M],block,pos[N];
    31 struct Query {
    32     int l,r,id;
    33     bool operator < (const Query &another) const {
    34         return l/block<another.l/block||(l/block==another.l/block&&r<another.r);
    35     }
    36 };
    37 Query q[M];
    38 inline int max(const int &a,const int &b) {
    39     return a>b?a:b;
    40 }
    41 class SegmentTree {
    42     #define _par >>1
    43     #define _left <<1
    44     #define _right <<1|1
    45     private:
    46         int smax[N<<2],lmax[N<<2],rmax[N<<2],len[N<<2];
    47         void push_up(const int &p) {
    48             lmax[p]=lmax[p _left];
    49             if(__builtin_expect(smax[p _left]==len[p _left],0)) lmax[p]=max(lmax[p],smax[p _left]+lmax[p _right]);
    50             rmax[p]=rmax[p _right];
    51             if(__builtin_expect(smax[p _right]==len[p _right],0)) rmax[p]=max(rmax[p],smax[p _right]+rmax[p _left]);
    52             smax[p]=max(max(lmax[p],rmax[p]),max(max(smax[p _left],smax[p _right]),rmax[p _left]+lmax[p _right]));
    53         }
    54     public:
    55         void build(const int &p,const int &b,const int &e) {
    56             len[p]=e-b+1;
    57             if(b==e) {
    58                 pos[b]=p;
    59                 return;
    60             }
    61             const int mid=(b+e)>>1;
    62             build(p _left,b,mid);
    63             build(p _right,mid+1,e);
    64         }
    65         void modify(const int &p) {
    66             smax[p]=lmax[p]=rmax[p]=smax[p]^1;
    67             for(register int q=p _par;q;q=q _par) push_up(q);
    68         }
    69     #undef _par
    70     #undef _left
    71     #undef _right
    72 };
    73 SegmentTree t;
    74 int main() {
    75     const int n=getint(),m=getint();
    76     block=__builtin_sqrt(n);
    77     t.build(1,1,n);
    78     for(register int i=1;i<=n;i++) p[i]=getint();
    79     for(register int i=0;i<m;i++) {
    80         const int l=getint(),r=getint();
    81         q[i]=(Query){l,r,i};
    82     }
    83     std::sort(&q[0],&q[m]);
    84     for(register int i=0,l=1,r=0;i<m;i++) {
    85         while(r<q[i].r) t.modify(pos[p[++r]]);
    86         while(l>q[i].l) t.modify(pos[p[--l]]);
    87         while(r>q[i].r) t.modify(pos[p[r--]]);
    88         while(l<q[i].l) t.modify(pos[p[l++]]);
    89         ans[q[i].id]=*((int*)&t+1);
    90     }
    91     for(register int i=0;i<m;i++) {
    92         __builtin_printf("%d
    ",ans[i]);
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    模拟+位运算 HDOJ 5491 The Next
    树状数组+二分||线段树 HDOJ 5493 Queue
    线段树(区间合并) HDOJ 3308 LCIS
    双端队列 HDOJ 3530 Subsequence
    BFS HDOJ 1242 Rescue
    Codeforces Round #321 (Div. 2)
    区间专题
    递推DP HDOJ 5459 Jesus Is Here
    补题列表2
    引用与指针的异同-基础篇
  • 原文地址:https://www.cnblogs.com/skylee03/p/8628848.html
Copyright © 2020-2023  润新知