zoukankan      html  css  js  c++  java
  • [loj2479]制胡窜

    建立后缀自动机,并用预处理出right集合,考虑对于一个长度为$len$且$right=left{ r_{1},r_{2}, cdots ,r_{k} ight}(r_{1}<r_{2}<cdots<r_{k})$(设字符串下标从1开始),有多少种方案使得其不合法(再用$c(n,2)$减去下面的$ans$)
    这就意味着对于一个任意一个$r$,都有$r-len+1le i<r$或$r-len+1le j<r$,分类讨论:
    1.存在$r_{a}<r_{b}<r_{c}$,满足$r_{b}-len+1ge r_{a}$且$r_{c}-len+1ge r_{b}$,那么a,b和c无法同时满足两个,即无解
    2.满足$r_{k}-len+1<r_{1}$,那么令$s=r_{1}-(r_{k}-len+1)$,则$ans=C(s,2)+scdot (n-1-s)+sum_{i=1}^{k-1}(r_{i+1}-r_{i})^{2}$
    3.两种情况都不满足,必然有i隔断了$r1,r2,cdots,r_{a}$,j隔断了$r_{b},r_{b+1},cdots,r_{k}$($ble a+1$)(令a和b分别为最大和最小的a和b),令A和B分别表示最大可能的a和最小可能的b(必然有$Ble A+1$),计算方案数:
    $ans=sum_{a=1}^{A}sum_{b=B}^{k}[ble a+1]egin{pmatrix} egin{Bmatrix} r_{1}-(r_{A}-len+1) (a=A) \ r_{a+1}-r_{a} (a<A) end{Bmatrix}end{pmatrix} egin{pmatrix} egin{Bmatrix} r_{B}-(r_{k}-len+1) (b=B) \ r_{b}-r_{b-1} (b>B)end{Bmatrix}end{pmatrix}$
    然后a和b的枚举范围修改为$ans=sum_{a=B-1}^{A}sum_{b=B}^{a+1}cdots$,这样就不需要$ble a+1$的判断了
    再调换枚举顺序,考虑$sum_{b=B}^{i+1}egin{pmatrix} egin{Bmatrix} r_{B}-(r_{k}-len+1) (b=B) \ r_{b}-r_{b-1} (b>B)end{Bmatrix}end{pmatrix})=r_{a+1}-r_{k}+len-1$
    代入原式,得到$ans=sum_{a=B-1}^{A}egin{pmatrix} egin{Bmatrix} r_{1}-(r_{A}-len+1) (a=A) \ r_{a+1}-r_{a} (a<A)end{Bmatrix}end{pmatrix}(r_{a+1}-r_{k}+len-1)$
    再对$a$分类讨论,即$ans=(r_{1}-(r_{A}-len+1))(r_{A+1}-r_{k}+len-1)+sum_{a=B-1}^{A}(r_{a+1}-r_{a})(r_{a+1}-r_{k}+len-1)$
    最后,我们相当于要在求right集合的时侯用线段树顺便维护:1.区间和;2.区间平方和;3.区间相邻两数乘积和;4.区间左右端点;5.区间中数的个数,然后就可以算出上面的式子了
     
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 200005
      4 #define ll long long
      5 #define L ls[k]
      6 #define R rs[k]
      7 #define mid (l+r>>1)
      8 struct ji{
      9     int nex,to;
     10 }edge[N<<1];
     11 struct node{
     12     int l,r;
     13     ll mul,sum[3];
     14 }tr[N*20];
     15 int V,VV,E,las,n,m,l,r,a[N],mx[N],nex[N],head[N],rt[N],ls[N*20],rs[N*20],ch[N][11],f[N][21];
     16 char s[N];
     17 ll C(int n){
     18     return n*(n-1LL)/2;
     19 }
     20 ll sqr(int n){
     21     return 1LL*n*n;
     22 }
     23 node up(node x,node y){
     24     node k;
     25     k.l=min(x.l,y.l);
     26     k.r=min(x.r,y.r);
     27     k.mul=x.mul+y.mul;
     28     if (x.sum[0]*y.sum[0])x.mul+=1LL*x.r*y.l;
     29     for(int i=0;i<3;i++)k.sum[i]=x.sum[i]+y.sum[i];
     30     return k;
     31 }
     32 void update(int &k,int l,int r,int x){
     33     if (!k)tr[k=++VV]=tr[0];
     34     if (l==r){
     35         tr[k].l=tr[k].r=tr[k].sum[1]=x;
     36         tr[k].sum[0]=1;
     37         tr[k].sum[2]=1LL*x*x;
     38         return;
     39     }
     40     if (x<=mid)update(L,l,mid,x);
     41     else update(R,mid+1,r,x);
     42     tr[k]=up(tr[L],tr[R]); 
     43 }
     44 int merge(int k1,int k2){
     45     if (k1*k2==0)return k1+k2;
     46     int k=++VV;
     47     L=merge(ls[k1],ls[k2]);
     48     R=merge(rs[k1],rs[k2]);
     49     tr[k]=up(tr[L],tr[R]); 
     50     return k;
     51 }
     52 int query1(int k,int l,int r,int x){//最后一个比x小 
     53     if (l==r)return l;
     54     if (tr[R].l>=x)return query1(L,l,mid,x);
     55     return query1(R,mid+1,r,x);
     56 }
     57 int query2(int k,int l,int r,int x){//第一个比x大 
     58     if (l==r)return l;
     59     if (tr[l].r>x)return query2(L,l,mid,x);
     60     return query2(R,mid+1,r,x);
     61 }
     62 node query(int k,int l,int r,int x,int y){
     63     if ((!k)||(l>y)||(x>r))return tr[0];
     64     if ((x<=l)&&(r<=y))return tr[k];
     65     return up(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
     66 }
     67 void add(int c){
     68     int p=las,np=las=++V;
     69     mx[np]=mx[p]+1;
     70     while ((p)&&(!ch[p][c])){
     71         ch[p][c]=np;
     72         p=nex[p];
     73     }
     74     if (!p)nex[np]=1;
     75     else{
     76         int q=ch[p][c];
     77         if (mx[q]==mx[p]+1)nex[np]=q;
     78         else{
     79             int nq=++V;
     80             mx[nq]=mx[p]+1;
     81             nex[nq]=nex[q];
     82             memcpy(ch[nq],ch[q],sizeof(ch[q]));
     83             nex[q]=nex[np]=nq;
     84             while ((p)&&(ch[p][c]==q)){
     85                 ch[p][c]=nq;
     86                 p=nex[p];
     87             }
     88         }
     89     }
     90 }
     91 void add(int x,int y){
     92     edge[E].nex=head[x];
     93     edge[E].to=y;
     94     head[x]=E++;
     95 }
     96 void dfs(int k,int fa){
     97     f[k][0]=fa;
     98     for(int i=1;i<=20;i++)f[k][i]=f[f[k][i-1]][i-1];
     99     for(int i=head[k];i!=-1;i=edge[i].nex)
    100         if (edge[i].to!=fa){
    101             dfs(edge[i].to,k);
    102             rt[k]=merge(rt[k],rt[edge[i].to]);
    103         }
    104 }
    105 int find(int k,int len){
    106     for(int i=20;i>=0;i--)
    107         if (mx[f[k][i]]>=len)k=f[k][i];
    108     return k;
    109 }
    110 ll query(int k,int len){
    111     int a=query1(k,1,n,tr[k].l+len-1),b=query2(k,1,n,tr[k].r-len+1);
    112     if (a+1<b)return 0;
    113     if (tr[k].r-len+1<tr[k].l){
    114         int s=tr[k].l-(tr[k].r-len+1);
    115         return C(s)+s*(n-1LL-s)+2*tr[k].sum[2]-2*tr[k].mul-sqr(tr[k].l)-sqr(tr[k].r); 
    116     }
    117     int aa=query2(k,1,n,a),bb=query1(k,1,n,b);
    118     return 1LL*(tr[k].l-(a-len+1))*(aa-tr[k].r+len-1)+(bb-aa)*(tr[k].r-len+1LL)+query(k,1,n,b,aa).sum[2]-query(k,1,n,bb,aa).mul;
    119 }
    120 int main(){
    121     scanf("%d%d%s",&n,&m,s);
    122     V=las=1;
    123     tr[0].l=n+1;
    124     for(int i=0;i<n;i++){
    125         add(s[i]-'0');
    126         a[i+1]=las;
    127         update(rt[las],1,n,i+1);
    128     }
    129     memset(head,-1,sizeof(head));
    130     for(int i=1;i<=V;i++)add(nex[i],i);
    131     for(int i=1;i<=m;i++){
    132         scanf("%d%d",&l,&r);
    133         printf("%lld
    ",C(n+1)-query(rt[find(a[r],r-l+1)],r-l+1));
    134     }
    135 }
    View Code
  • 相关阅读:
    基于redis实现的延迟消息队列
    Redis实现求交集操作结果缓存的设计方案
    限流算法之漏桶算法、令牌桶算法
    Apache设置防DDOS模块mod_evasive
    FastCGI技术
    详解强大的SQL注入工具——SQLMAP
    nginx根据域名做http,https分发
    Nginx配置SSL证书部署HTTPS网站
    JProfiler学习笔记
    Mysql压测工具mysqlslap 讲解
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13067694.html
Copyright © 2011-2022 走看看