首页 > 其他分享 >题解 CF741E Arpa’s abnormal DNA and Mehrdad’s deep interest

题解 CF741E Arpa’s abnormal DNA and Mehrdad’s deep interest

时间:2024-01-18 16:46:02浏览次数:18  
标签:lg DNA min int 题解 Mehrdad mid maxn return

CF741E Arpa’s abnormal DNA and Mehrdad’s deep interest

记 \(R_{i}\) 表示把 \(T\) 插入在 \(S\) 的第 \(i\) 位后组成的字符串。有 \(q\) 组询问,给定 \((x,y,l,r)\),求 \(\min_{i} R_{i},({i\in[l,r],i\%k\in[x,y]})\)。

一个暴力的想法是先把 \(R_{i}\) 的排名求出来,这显然可以 SA 或者 二分 + Hash 求 lcp。考虑根号分治:对于 \(k>\sqrt n\),显然不会有超过 \(\sqrt n\) 个连续区间,暴力查 ST 表即可。对于 \(k\le \sqrt n\),离线处理,对于每个 \(k\),我们把 \(\%k\) 相同的点拿出来,发现对于一个询问仍然是区间查询,且一个询问只会被拆分成 \(k\) 个。仍然可以暴力建立 ST 表,因为数组大小之和是调和级数。询问的个数复杂度是 \(O(n\sqrt n)\)。

故总的复杂度为 \(O(n\sqrt n+n\log^2 n+n\lg\log n)\)。实现时需注意常数。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=2e5+5, mo=998244353, B=335;

int n,m,q;
char s[maxn], t[maxn];
ll f[maxn], g[maxn], pw[maxn];
int sa[maxn], rk[maxn], lg[maxn], w[maxn][20];

int calc(int x,int len) {
    if(len<=x) return f[len];
    if(len<=x+m) return (f[x]*pw[len-x]%mo+g[len-x])%mo;
    return ((f[x]*pw[m]%mo+g[m])%mo*pw[len-x-m]%mo+f[len-m]-f[x]*pw[len-x-m]%mo+mo)%mo;
}

bool cmp(int x,int y) {
    int l=1, r=n+m, pos=0;
    while(l<=r) {
        int mid=l+r>>1;
        if(calc(x,mid)==calc(y,mid)) pos=mid, l=mid+1;
        else r=mid-1;
    }
    if(pos==n+m) return x<y;
    ++pos;
    char c1,c2;
    if(pos<=x) c1=s[pos];
    else if(pos<=x+m) c1=t[pos-x];
    else c1=s[pos-m];
    if(pos<=y) c2=s[pos];
    else if(pos<=y+m) c2=t[pos-y];
    else c2=s[pos-m];
    return c1<c2;
}

struct node {
    int x,y,l,r,id;
};
vector<node> e[B];
int ans[maxn];

int ask(int l,int r) {
    if(l>r) return n+1;
    int k=lg[r-l+1];
    return min(w[l][k],w[r-(1<<k)+1][k]);
}

int ww[maxn][20];

int ask2(int l,int r) {
    if(l>r) return n+1;
    int k=lg[r-l+1];
    return min(ww[l][k],ww[r-(1<<k)+1][k]);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin>>s+1>>t+1>>q;
    n=strlen(s+1), m=strlen(t+1);
    pw[0]=1; lg[1]=0;
    for(int i=2;i<=n+1;i++) lg[i]=lg[i>>1]+1;
    for(int i=1;i<=n+m;i++) pw[i]=pw[i-1]*131%mo;
    for(int i=1;i<=n;i++) f[i]=(f[i-1]*131+s[i]-'a')%mo;
    for(int i=1;i<=m;i++) g[i]=(g[i-1]*131+t[i]-'a')%mo;
    for(int i=0;i<=n;i++) sa[i]=i;
    stable_sort(sa,sa+n+1,cmp);
    /*
    for(int i=0;i<=n;i++) {
        cout<<sa[i]<<'\n';
        for(int j=1;j<=sa[i];j++) cout<<s[j];
        for(int j=1;j<=m;j++) cout<<t[j];
        for(int j=sa[i]+1;j<=n;j++) cout<<s[j];
        cout<<'\n';
    }
    */
    for(int i=0;i<=n;i++) rk[sa[i]]=i;
    // for(int i=0;i<=n;i++) w[i][0]=rk[i];
    for(int j=1;(1<<j)<=n+1;j++) {
        for(int i=0;i+(1<<j)-1<=n;i++) {
            w[i][j]=min(w[i][j-1],w[i+(1<<j-1)][j-1]);
        }
    }
    sa[n+1]=-1;
    for(int i=1;i<=q;i++) ans[i]=n+1;
    for(int i=1;i<=q;i++) {
        int l,r,k,x,y; cin>>l>>r>>k>>x>>y;
        if(k>=B) {
            int ml=l%k, res=n+1;
            if(ml<x) l+=x-ml;
            else if(ml>y) l+=(x+k-ml);
            else {
                res=min(ask(l,min(l+y-ml,r)),res);
                l+=(x+k-ml);
            }
            int mr=r%k;
            if(mr>y) r-=mr-y;
            else if(mr<x) r-=(mr+k-y);
            else {
                res=min(ask(max(l,r-(mr-x)),r),res);
                r-=(mr+k-y);
            }
            while(l<=r) {
                res=min(res,ask(l,l+y-x));
                l+=k;
            }
            ans[i]=res;
        }else {
            e[k].push_back((node){x,y,l,r,i});
        }
    }
    for(int k=1;k<B;k++) {
        for(int v=0;v<k;v++) {
            int cnt=0;
            for(int d=v;d<=n;d+=k) ww[++cnt][0]=rk[d];
            for(int j=1;(1<<j)<=cnt;j++) {
                for(int i=1;i+(1<<j)-1<=cnt;i++) {
                    ww[i][j]=min(ww[i][j-1],ww[i+(1<<j-1)][j-1]);
                }
            }
            for(auto p:e[k]) {
                if(p.x>v||p.y<v) continue;
                int l=p.l, r=p.r;
                l=l+(v-(l%k)+k)%k;
                r=r-((r%k)-v+k)%k;
                l=(l-v)/k+1, r=(r-v)/k+1;
                ans[p.id]=min(ans[p.id],ask2(l,r));
            }
        }
    }
    for(int i=1;i<=q;i++) cout<<sa[ans[i]]<<' '; cout<<'\n';
    return 0;
}

标签:lg,DNA,min,int,题解,Mehrdad,mid,maxn,return
From: https://www.cnblogs.com/sssooommm/p/17972796

相关文章

  • CF1921 F Sum of Progression 题解
    QuestionCF1921FSumofProgression给定一个序列\(\{a\}\),有\(q\)组询问,对于每组询问\(s,d,k\),求\[a_s+a_{s+d}\cdot2+\cdots+a_{s+d(k-1)}\cdotk\]Solution\(s,d,k\)其实就是在描述一个等差数列考虑到\(d\timesk\len\)如果\(d\)很大,那么就意味着\(k\)很......
  • 题解 CF653F Paper task
    CF653FPapertask给定一个长度为\(n\)和括号串,求本质不同的合法括号串个数。\(n\le5\times10^5\)。考虑如果不是求本质不同,可以想到DP。设\(f_{i}\)表示以\(i\)结尾的括号串数,容易发现\(f_{i}=f_{t_{i}-1}+1\),其中\(t_{i}\)表示与\(i\)匹配的左括号位置。用栈......
  • 【深入挖掘Java技术】「源码原理体系」盲点问题解析之HashMap工作原理全揭秘(下)
    承接上文在阅读了上篇文章《【深入挖掘Java技术】「源码原理体系」盲点问题解析之HashMap工作原理全揭秘(上)》之后,相信您对HashMap的基本原理和基础结构已经有了初步的认识。接下来,我们将进一步深入探索HashMap的源码,揭示其深层次的技术细节。通过这次解析,您将更深入地理解HashMap的......
  • chrome浏览器闪屏问题解决
    描述:我在浏览B站时,在打字时突然出现了闪屏,反应很强烈!一输入就出现!我还一直以为是电脑显卡出了问题!后来查询资料发现这是谷歌很久以前的一个bug,至今都没有修复!至少在我发帖之前一直是没有解决的!开启硬件加速若想使用硬件加速,可以在网址栏输入:chrome://flags/选择ChooseANGL......
  • CF1633B题解
    Minority题面翻译给定一个\(01\)字符串\(s\),定义\(c_k(l,r)\)表示\(s\)的由下标为\([l,r]\)中的字母构成的连续子串中\(k\)的个数。定义\(f(l,r)=\begin{cases}c_0(l,r)&c_0(l,r)<c_1(l,r)\\c_1(l,r)&c_0(l,r)>c_1(l,r)\\0&c_0(l,r)=c_1(l,r)\end{cases}\),求......
  • P3391 文艺平衡树 题解
    QuestionP3391文艺平衡树写一种数据结构维护有序数列,需要完成以下操作:翻转一个区间,例如原有的序列是\(5,3,3,2,1\),翻转区间是\([2,4]\)的话,结果是\(5,2,3,4,1\)Solution这道题的表达是\(Splay\)但是\(Splay\)的代码实现比较困难,考虑使用FHQTreap。先思考如何将一......
  • CF1633A题解
    Div.7题面翻译给定\(t\)组数据。每组数据给定一个数\(n\)(\(10\len\le999\))。每次操作可以修改\(n\)任意一位上的数,将这一位上的数修改为\(0\sim9\)之间的任意数。要求使用最少的修改次数使这个数修改后是\(7\)的倍数,并且没有多余的前导\(0\)。输出修改后的数,如......
  • CF1637A题解
    SortingParts题面翻译给定一个长度为n的数组a。你可以执行恰好一次操作。每次操作选择一个在[1,n-1]内的整数len,然后将数组a中长度为len的前缀和长度为n-len的后缀分别排序。请判断是否能够通过操作,使得最终的数组a不满足\foralli\in[1,n),a_i<=a(i+1)。数据范......
  • [ARC169E] Avoid Boring Matches 题解
    题目链接首先考虑无解的情况,一个显然的观察是如果R的个数大于一半,那么无论如何都会出现两个R比赛的情况,小于一半时我们可以调整使得B全都在前面,显然有解。接下来问题变为找到最优可行解,但是状态的合法性不是显然的,我们先尝试判定这个问题。先考虑第一轮比赛,显然我们想让......
  • SP839Optimal Marks 题解
    part1:建图二进制异或,每一位互不干扰。所以对每一位分开来考虑。然后变成了一个经典的模型。当前每一个未确定点有两个选择:变成\(1\),变成\(0\);已经确定的点只能选它本身的值。于是构造思路非常套路了:构造虚点\(S\)、\(T\)。对于一个点\(u\),从\(S\)连向\(u\)一条边,值为......