先来一波胡测(未完)

Round 0

T1 po姐的送温暖题,但是我为啥就没去想 >.<

统计从左上到右下两条路径不相交的方案数。

如果只有一条路这是普及组。

记 $f(i,j,k,l)$ 为从 $(i,j)$到$(k,l)$的方案数。

如果我们没有相交,显然有

$$ans = f(2,1,n,m-1) \cdot f(1,2,n-1,m)$$

接下来考虑只统计相交的路径。

神思路:

找到最后一个交点,转一下变为$(2,1)$走到$(n-1,m)$的路径和一条从$(1,2)$走到$(n,m-1)$的路径

然后我们惊讶地发现原先每种不合法的方案对应一个反转后的方案。

所以相交的对数为

$$f(1,2,n,m-1) \cdot f(2,1,n-1,m)$$

思路很神,但是代码就没什么意思了。。。

T2 zrt的题,HEOI Day2 T3加强版

在一个子序列自动机和一个后缀自动机上dfs记忆化,有$O(n)$的边,$O(n^2)$的状态。

然后就没有然后了。。。

#include <cstdio>
#include <cstring>

#define N 4010
#define LL long long
#define mod 1000000007

using namespace std;

struct node{
    node *ch[26],*fa;
    int len,id;
    LL v;
};

struct SAM{
    node *root,spT[N<<1],*now;

    int tot;

    void addin(char c){
        int t=c-‘a‘;
        node *np=&spT[++tot],*p=now;
        np->id=tot;
        np->len=p->len+1;
        now=np;
        for(;p&&!p->ch[t];p=p->fa) p->ch[t]=np;
        if(!p) np->fa=root;
        else{
            if(p->ch[t]->len==p->len+1) np->fa=p->ch[t];
            else{
                node *nq=&spT[++tot],*q=p->ch[t];
                *nq=*q;
                nq->len=p->len+1;
                nq->id=tot;
                q->fa=np->fa=nq;
                for(;p&&p->ch[t]==q;p=p->fa) p->ch[t]=nq;
            }
        }
    }

    void dfs(node *p){
        p->v=1;
        for(int i=0;i<26;i++)
            if(p->ch[i]){
                if(!p->ch[i]->v) dfs(p->ch[i]);
                (p->v+=p->ch[i]->v)%=mod;
            }
    }

    void build(char *S){
        now=root=&spT[tot=1];
        int len=strlen(S);
        for(int i=0;i<len;i++) addin(S[i]);
        dfs(root);
    }
}A1,A2;

struct SBM{
    node spT[N],*root,*a[26];
    int tot;

    void build(char *S){
        root=&spT[tot=1];
        root->id=tot;
        for(int i=0;i<26;i++) a[i]=NULL;
        for(int i=strlen(S)-1;~i;i--){
            node *p=&spT[++tot];
            p->id=tot;
            p->v=1;
            memcpy(p->ch,a,sizeof(a));
            for(int t=0;t<26;t++)
                if(p->ch[t]) (p->v+=p->ch[t]->v)%=mod;
            int t=S[i]-‘a‘; a[t]=p;
        }
        memcpy(root->ch,a,sizeof(a));
        for(int i=0;i<26;i++)
            if(root->ch[i]) root->v+=root->ch[i]->v;
    }
}B1,B2;

char S1[N],S2[N];
LL f[N][N];

LL dfs(node *a,node *b){
    if(!b) return a->v;
    if(f[a->id][b->id]!=-1) return f[a->id][b->id];
    LL ans=0;
    for(int t=0;t<26;t++)
        if(a->ch[t]) (ans+=dfs(a->ch[t],b->ch[t]))%=mod;
    return f[a->id][b->id]=ans;
}

int main(){
    scanf("%s%s",S1,S2);
    A1.build(S1);
    A2.build(S2);
    B1.build(S1);
    B2.build(S2);
    memset(f,-1,sizeof(f));
    printf("%lld\n",dfs(A1.root,A2.root));
    memset(f,-1,sizeof(f));
    printf("%lld\n",dfs(A1.root,B2.root));
    memset(f,-1,sizeof(f));
    printf("%lld\n",dfs(B1.root,A2.root));
    memset(f,-1,sizeof(f));
    printf("%lld\n",dfs(B1.root,B2.root));
    return 0;
}

T3呀。。算了吧,不过

是非常好的提答题(比CTSC的好多了)

Round 1

膜 ioi ZYF laekov

难了一点但是题很好。

T1

ioi大爷的题,LCT 莫对

ioi:“这种做法虽然在修改上多了一个log,但是由于常熟十分小,期望分数还是100分的”

报警了。

写的$O(nsqrt(n))$算法

首先对询问的串分块,然后每个块建AC自动机

查询$O(msqrt(n)+m|S|)$

然而:

int t=0;
for(int i=1;i<=n;i++){
    l[i]=t;
    scanf("%s",S1+t);
    t=strlen(S1);
    r[i]=t-1;
    Kmp_init(i);
}

QAQ读入是$O(n^2)$的变成30分真是醉了。

改了被卡常95分,不想(hui)卡常,不管了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <ctime>
#include <cctype>

#define N 500010
#define L(x) ((x-1)*size+1)
#define R(x) (min(x*size,n))

using namespace std;

inline int max(int a,int b){
    if(a<b) return b;
    return a;
}

char S1[N],S2[N];
int n,m,size,l[N],r[N],tot;

struct node{
    node *ch[26],*fail;
    int v,len;
}*q[N],spT[500010];

struct ACam{
    node* root;

    inline void init(){
        root=&spT[++tot];
    }

    inline void addin(int l,int r){
        node* tmp=root;
        for(int i=l;i<=r;i++){
            int t=S1[i]-‘a‘;
            if(!tmp->ch[t]) tmp->ch[t]=&spT[++tot];
            tmp=tmp->ch[t];
        }
        tmp->v++;
        tmp->len=r-l+1;
    }

    int st,en;

    inline void getfail(){
        q[st=en=1]=root;
        while(st<=en){
            node* tmp=q[st++];
            if(tmp!=root){
                tmp->len=max(tmp->len,tmp->fail->len);
                tmp->v+=tmp->fail->v;
            }
            for(int t=0;t<26;t++){
                if(tmp->ch[t]!=NULL){
                    if(tmp==root) tmp->ch[t]->fail=root;
                    else tmp->ch[t]->fail=tmp->fail->ch[t];
                    q[++en]=tmp->ch[t];
                }
                else{
                    if(tmp==root) tmp->ch[t]=root;
                    else tmp->ch[t]=tmp->fail->ch[t];
                }
            }
        }
    }

    inline int ask(char *c){
        int ans=0;
        node* tmp=root;
        while(*c!=‘\0‘){
            int t=*c-‘a‘;
            tmp=tmp->ch[t];
            if(tmp->v) ans=max(ans,tmp->len);
            c++;
        }
        return ans;
    }
}AM[620];

int wb[N],f[N],lk[N],rk[N],ft[N],nt,tot_n=0;
char S[N];

inline void Kmp_init(int x){
    nt=0;
    for(int i=l[x];i<=r[x];i++) S[nt++]=S1[i];
    f[0]=0; f[1]=0;
    for(int i=1;i<nt;i++){
        int j=f[i];
        while(j&&S[i]!=S[j]) j=f[j];
        f[i+1] = S[i]==S[j]? j+1:0;
    }
    lk[x]=tot_n;
    for(int i=0;i<nt;i++) ft[tot_n++]=f[i];
    rk[x]=tot_n-1;
}

inline int ask(int x,char *St){
    nt=0;
    for(int i=l[x];i<=r[x];i++) S[nt++]=S1[i];
    int tmp=0;
    for(int i=lk[x];i<=rk[x];i++) f[tmp++]=ft[i];
    int nl=strlen(St),j=0;
    for(int i=0;i<nl;i++){
        while(j&&S[j]!=St[i]) j=f[j];
        if(S[j]==St[i]) j++;
        if(j==nt) return nt;
    }
    return 0;
}

inline int com_ask(int l,int r,char* S){
    int lb=wb[l],rb=wb[r],ans=0;
    if(lb==rb){
        for(int i=l;i<=r;i++)
            ans=max(ans,ask(i,S));
    }
    else{
        if(l!=L(lb)){
            for(int i=l;i<=R(lb);i++)
                ans=max(ans,ask(i,S));
        }
        for(int i= ((l==L(lb))? lb:lb+1);i<= ((r==R(rb))?rb:rb-1);i++)
            ans=max(ans,AM[i].ask(S));
        if(r!=R(rb)){
            for(int i=L(rb);i<=r;i++)
                ans=max(ans,ask(i,S));
        }
    }
    return ans;
}

int main(){
    scanf("%d%d",&n,&m);
    int t=0;
    char ch;
    for(int i=1;i<=n;i++){
        l[i]=t;
        while(!isalpha(ch=getchar()));
        S1[t++]=ch;
        while(isalpha(ch=getchar())) S1[t++]=ch;
        r[i]=t-1;
        Kmp_init(i);
    }
    size=(int)sqrt(n+0.5);
    for(int i=1;i<=n;i++) wb[i]=(i-1)/size+1;
    for(int i=1;i<=wb[n];i++) AM[i].init();
    for(int i=1;i<=n;i++) AM[wb[i]].addin(l[i],r[i]);
    for(int i=1;i<=wb[n];i++) AM[i].getfail();
    for(int i=1,l,r;i<=m;i++){
        scanf("%d%d",&l,&r);
        t=0;
        while(!isalpha(ch=getchar()));
        S2[t++]=ch;
        while(isalpha(ch=getchar())) S2[t++]=ch;
        S2[t]=‘\0‘;
        printf("%d\n",com_ask(l,r,S2));
    }
    return 0;
}

T2

QAQ,QAQ

一直在做T1 T3,没有理T2,最后发现裸的KD-tree 优化dp呀[捂脸]

ZYF业界良心。

(代码还是算了吧)

T3

QAQ还不会,待补完。

时间: 2024-10-18 04:11:10

先来一波胡测(未完)的相关文章

[daily][optimize] 去吃面 (python类型转换函数引申的性能优化)(未完待续)

前天,20161012,到望京面试.第四个职位,终于进了二面.好么,结果人力安排完了面试时间竟然没有通知我,也没有收到短信邀请.如果没有短信邀请门口的保安大哥是不让我进去大厦的.然后,我在11号接到了面试官直接打来的电话,问我为啥还没到,我说没人通知我我不知道呀.结果我就直接被他邀请去以访客的身份参加面试了.不知道人力的姑娘是不是认识我,且和我有仇,终于可以报复了... 然后,我终于如约到了,面试官带着我去前台登记.前台的妹子更萌...认为我是面试官,面试官是才是来面试的.我气质真的那么合吗?

某度质量部测试开发面试题1(未完待续)

点击链接加入QQ群 522720170(免费公开课.视频应有尽有):https://jq.qq.com/?_wv=1027&k=5C08ATe 1. 黑盒测试和白盒测试常用的测试方法有哪些?举例说明. 答:白盒测试:逡辑覆盖法,主要包括诧句覆盖,判断覆盖,条件覆盖,判断条件覆盖,组合条件覆盖.路径覆盖. 黑盒测试:等价划分类,边界值分析,错诨推测法等 2. 静态测试和动态测试的概念. 答:静态方法是不运行被测程序本身,仅通过分析和检查源程序的语法.结构.过程.接口等来检查程序的正确性.对需求规格

whatweb.rb 未完待续

#!/usr/bin/env ruby #表示ruby的执行环境 =begin # ruby中用=begin来表示注释的开始 .$$$ $. .$$$ $. $$$$ $$. .$$$ $$$ .$$$$$$. .$$$$$$$$$$. $$$$ $$. .$$$$$$$. .$$$$$$. $ $$ $$$ $ $$ $$$ $ $$$$$$. $$$$$ $$$$$$ $ $$ $$$ $ $$ $$ $ $$$$$$. $ `$ $$$ $ `$ $$$ $ `$ $$$ $$' $ `$

把握linux内核设计思想系列(未完待续......)

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 把握linux内核设计思想(一):系统调用 把握linux内核设计思想(二):硬中断及中断处理 把握linux内核设计思想(三):下半部机制之软中断 把握linux内核设计思想(四):下半部机制之tasklet 把握linux内核设计思想(五):下半部机制之工作队列及几种机制的选择 把握linux内核设计思想(六):内核时钟中断 把握linux内核设计思想(七):内核定时器和

细菌觅食优化算法:理论基础,分析,以及应用(未完)

原作者:Swagatam Das,Arijit Biswas,Sambarta Dasgupta,和Ajith Abraham  [摘 要]细菌觅食优化算法(Bacterial foraging optimization algorithm[BFOA])已经被分布式优化和控制的同行们当作一种全局性的优化算法接受.BFOA是由大肠杆菌的群体觅食行为所启发而总结出来 的.BFOA已经吸引了足够多的研究者的注意,由于它出现在解决真实世界中一些应用领域上优化问题的高效性.E.coli 的群体策略的生物基

Linux设备驱动开发学习(2):Linux设备驱动简介(未完)

(未完待续......)

[译]App Framework 2.1 (1)之 Quickstart (未完待续)

最近有移动App项目,选择了 Hybrid 的框架Cordova  和  App Framework 框架开发. 本来应该从配置循序渐进开始写的,但由于上班时间太忙,这段时间抽不出空来,只能根据心情和兴趣,想到哪写到哪,前面的部分以后慢慢补上. App Framework 前生是是叫 jqMobi 注意大家不要和 jQuery Mobile 混淆了,它们是两个不同的框架,一开始我还真混淆了0.01秒. 这里我先翻译一下Quickstart 部分,一是自己工作上用的上,二是也想顺便练练英文,最关键

数据结构与算法之--高级排序:shell排序和快速排序【未完待续】

高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序的是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希尔(shell)排序 希尔排序是基于插入排序的,首先回顾一下插入排序,假设插入是从左向右执行的,待插入元素的左边是有序的,且假如待插入元素比左边的都小,就需要挪动左边的所有元素,如下图所示: ==> 图1和图2:插入右边的temp柱需要outer标记位左边的五个柱子都向右挪动 如图3所示,相比插入排序

gulp 入门使用指南(未完)

其实网上有一大把入门指南了,官网上也讲得很清楚.怎么安装,有哪些方法,我在网上已经看到很多很多很多了. 可是我还是很懵逼.不能理解为什么要使用这些工具,不知道学习了这些方法该怎么用,在哪里用.光看文档是学不会的,得有实战!实战啊!我感受不到这些新技术的好处.所以最初学习的时候,我迫切地渴望能有一个人,一篇文章,能通过一个具体的项目来指引一下我.然鹅并没有.(在小公司的坏处,没有指导,突破不了,还懒) 现在我对gulp也还是懵懵哒.只能慢慢写咯. 几乎每一个前端工具都对应了它自己的配置文件,nod