zoukankan      html  css  js  c++  java
  • bzoj 4358: permu 莫队

      第一步先莫队分块。

      对于每一块l~r,初始右端点设为r+1,然后每个询问先将右端点往右移,然后处理询问在l~r之间的部分,最后用一个栈再把l~r的复原。

      具体来说是维护两个数组now1和now2,一个向右最长的长度,一个向左的长度,每插入一个值x,用x+1的now2更新x的now2,用x-1的now1更新x的now1,now1[x]+now2[x]-1可能为最终答案,再把x所在的最长区间的左右端点的now数组更新,中间的值不需要更新,因为不可能再往中间插入数了。

      有生以来第一次bzoj榜一。

      

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define N 50005
     6 #define d 223
     7 using namespace std;
     8 int n,m;
     9 int c[N];
    10 int ans[N];
    11 struct node
    12 {
    13     int l,r,id,yuan;
    14     friend bool operator < (node aa,node bb)
    15     {
    16         if(aa.id!=bb.id)return aa.id<bb.id;
    17         return aa.r<bb.r;
    18     }
    19 }a[N];
    20 int now1[N],now2[N];
    21 int st1[N*2],st2[N*2],top;
    22 int main()
    23 {
    24     scanf("%d%d",&n,&m);
    25     for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    26     for(int i=1;i<=m;i++)
    27     {
    28         scanf("%d%d",&a[i].l,&a[i].r);
    29         a[i].yuan=i;a[i].id=(a[i].l-1)/d+1;
    30     }
    31     sort(a+1,a+m+1);
    32     int as=0;int r=0,t=0;
    33     for(int i=1;i<=m;i++)
    34     {
    35         if(a[i].id!=a[i-1].id)
    36         {
    37             as=0;
    38             memset(now1,0,sizeof(now1));
    39             memset(now2,0,sizeof(now2));
    40             r=t=a[i].id*d;
    41         }
    42         while(a[i].r>r)
    43         {
    44             r++;
    45             now1[c[r]]=now1[c[r]+1]+1;
    46             now2[c[r]]=now2[c[r]-1]+1;
    47             int tt=now1[c[r]]+now2[c[r]]-1;
    48             now2[c[r]+now1[c[r]]-1]=tt;
    49             now1[c[r]-now2[c[r]]+1]=tt;
    50             as=max(as,tt);
    51         }
    52         int tmp=as;top=0;
    53         for(int j=a[i].l;j<=min(a[i].r,t);j++)
    54         {
    55             now1[c[j]]=now1[c[j]+1]+1;
    56             now2[c[j]]=now2[c[j]-1]+1;
    57             int tt=now1[c[j]]+now2[c[j]]-1;
    58             int rr=c[j]+now1[c[j]]-1;int ll=c[j]-now2[c[j]]+1;
    59             st1[++top]=rr;st2[top]=now2[rr];
    60             st1[++top]=ll;st2[top]=now1[ll];
    61             now2[rr]=tt;
    62             now1[ll]=tt;
    63             tmp=max(tmp,tt);
    64         }
    65         for(int j=top;j>=1;j--)
    66         {
    67             if(j%2==0)now1[st1[j]]=st2[j];
    68             else now2[st1[j]]=st2[j];
    69         }
    70         for(int j=a[i].l;j<=min(a[i].r,t);j++)
    71         {
    72             now1[c[j]]=now2[c[j]]=0;
    73         }
    74         ans[a[i].yuan]=tmp;
    75     }
    76     for(int i=1;i<=m;i++)printf("%d
    ",ans[i]);
    77     return 0;
    78 }
  • 相关阅读:
    bzoj 3572 [Hnoi2014]世界树 (虚树+树形dp)
    2018 计算之道初赛第二场 阿里巴巴的手机代理商(困难)(反向可持久化Trie)
    hdu 3089 (快速约瑟夫环)
    Codeforces Round #479 (Div. 3)
    牛客练习赛17
    BNU校赛总决赛J 小白兔小灰兔 相交计算几何模板
    2018BNU校赛总决赛
    Educational Codeforces Round 43 (Rated for Div. 2) ABCDE
    Codeforces Round #478 (Div. 2) ABCDE
    牛客练习赛 16
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6395159.html
Copyright © 2011-2022 走看看