• 集训Day1


    雅礼集训2017Day1的题

    感觉上不可做实际上还挺简单的吧

    T1

    区间加 区间除法向下取整

    查询区间和 区间最小值

    大力上线段树,把除法标记推到底,加法标记就是按照线段树的来

    先拿30

    然后60的数据随机不知道该怎么做

    开始YY

    那个“向下取整”的tag并不能累加

    所以考虑转化

    除法->减法

    如果一个区间要减的都是一样的数,直接减就行了,如果不一样,就递归下去,反正1个数肯定减的是一样的

    本来想拿60,结果A了

    T2

    n*n的棋盘(n = 1000)每次把找一行,把它的颜色序列copy下来涂到一列上

    问最少多少次能把整个棋盘涂黑

    首先 全白肯定无解

    其次 只要把一行涂黑 之后涂n次就可以了

    然后 大力模拟发现并没有比这个优的策略

    于是一顿乱搞

    我们枚举第i行,假装要把他弄成全1的。

    设第i行的0的数量为cc[i],那么考虑第i列是否含有1,如果含有1那么就可以用含有1的那列的那行给第i行所有0的地方赋值,需要cc[i]步。

    如果第i列不含有1,我们要花1次操作给第i列搞个1出来,所以答案是cc[i]+1步。

    每行取个min

    听说是签到题...数据极水 被各种对的不对的做法爆切

    T3

    w 为两字符串,定义:

    1. $w[l,r]$  表示字符串 $w$ 在区间 $[l,r]$中的子串;
    2. $w$ 在 $s $中出现的频率定义为$w$ 在 $s$  中出现的次数;
    3. $f(s,w,l,r)$表示 $w[l,r]$ 在 $s$ 中出现的频率。

    比如 $f(ababa,aba,1,3)=2$。

    现在给定串 $s$,$m$个区间 $[l,r] $ 和长度 $k$ ,你要回答 $q$  个询问,每个询问给你一个长度为 $k$  的字符串 $w$  和两个整数 $a,b$,求:

    $sumlimits_{i = a} ^ b f(s, w, l_i, r_i)$

    重要条件

    $sum w_i$ 是个定值

    所以很eazy看了题解后想到要写两种做法

    首先考虑k小的情况

    这种情况我们可以用SAM暴力处理出right集合计算每一个子串在当前串出现的次数

    我的暴力永远比别人慢系列

    用莫队可以把O(n^2 k ^2)优化到(n sqrt n k ^2)写写写 

    k大时可以考虑在SAM的parent树上跑一个倍增

    暴力记前缀然后倍增往上跳找到后缀

    这样遍历每个子串就可以做了

    这是什么完全不可做的毒瘤题啊妈妈带我回家吧我不学OI了

    嗯 抬头 微笑

    感觉没看到签到题有点亏...想T1想了2个小时有点不应该

    然后1个小时迅速切T2

    T3就没时间想了只能n^3的KMP

    最后100 + 100 + 30

    感觉拿了个大众分?

    2018.6.6upd

    代码写完了 贴一下

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);x = 10 * x + ch - '0',ch = getchar());
        return x * f; 
    }
    inline LL Lread()
    {
        LL x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);x = 10 * x + ch - '0',ch = getchar());
        return x * f; 
    }
    const int maxn = 1e5 + 10;
    int n,m;
    LL a[maxn];
    LL minx[maxn << 2],sum[maxn << 2],maxx[maxn << 2],add[maxn << 2];
    #define ls (x << 1)
    #define rs ((x << 1) | 1)
    inline void pushup(int x){minx[x] = min(minx[ls],minx[rs]);sum[x] = sum[ls] + sum[rs];maxx[x] = max(maxx[ls],maxx[rs]);}
    inline void pushdown(int x,int l,int r)
    {
        if(add[x])
        {
            add[ls] += add[x];add[rs] += add[x];
            int mid = (l + r) >> 1; 
            sum[ls] += add[x] * (mid - l + 1);sum[rs] += add[x] * (r - mid);
            minx[ls] += add[x];minx[rs] += add[x];maxx[ls] += add[x];maxx[rs] += add[x];
            add[x] = 0;
        }
    }
    inline void build(int x,int l,int r)
    {
        if(l == r)
        {
               maxx[x] = minx[x] = sum[x] = a[l];
               return;
        }
        add[x] = 0;
        int mid = (l + r) >> 1;
        build(ls,l,mid);build(rs,mid + 1,r);
        pushup(x);
    }
    inline void update1(int x,int l,int r,int L,int R,int c) //Add
    {
        if(L <= l && r <= R)
        {
               add[x] += c;
               sum[x] += (r - l + 1) * c;
               minx[x] += c;maxx[x] += c;
               return;
        }
        pushdown(x,l,r);int mid = (l + r) >> 1;
        if(L <= mid)update1(ls,l,mid,L,R,c);
        if(R > mid)update1(rs,mid + 1,r,L,R,c);
        pushup(x);
    }
    inline void update2(int x,int l,int r,int L,int R,int d) //Div
    {
        if(L <= l && r <= R)
        {
            if(minx[x] == maxx[x] || ((maxx[x] % d == 0) && (maxx[x] - 1 == minx[x])))
            {
                LL delta = maxx[x] - (LL)floor((1.0 * maxx[x] / d));
                add[x] -= delta;
                minx[x] -= delta;maxx[x] -= delta;
                sum[x] -= 1LL *delta * (r - l + 1);
                return;
            }
            //return;
        }
        pushdown(x,l,r);int mid = (l + r) >> 1;
        if(L <= mid)update2(ls,l,mid,L,R,d);
        if(R > mid)update2(rs,mid + 1,r,L,R,d);
        pushup(x);
    }
    inline LL query1(int x,int l,int r,int L,int R) //Min
    {
        if(L <= l && r <= R)return minx[x];
        pushdown(x,l,r);
        int mid = (l + r) >> 1;
        LL ans = 21474832333333LL;
        if(L <= mid)ans = min(ans,query1(ls,l,mid,L,R));
        if(R > mid)ans = min(ans,query1(rs,mid + 1,r,L,R));
        return ans;
    }
    inline LL query2(int x,int l,int r,int L,int R) //Sum
    {
        if(L <= l && r <= R)return sum[x];
        pushdown(x,l,r);int mid = (l + r) >> 1;LL ans = 0;
        if(L <= mid)ans += query2(ls,l,mid,L,R);
        if(R > mid)ans += query2(rs,mid + 1,r,L,R);
        return ans;
    }
    
    int main()
    {
        n = read(),m = read();
        for(int i=1;i<=n;i++)a[i] = Lread();
        build(1,1,n);
        while(m--)
        {
            int opt = read(),l = read() + 1,r = read() + 1;
            if(opt == 1)
            {
                int c = read();
                update1(1,1,n,l,r,c);
            }
            if(opt == 2)
            {
                int d = read();
                update2(1,1,n,l,r,d);
            }
            if(opt == 3)
            {
                LL ans = query1(1,1,n,l,r);
                printf("%lld
    ",ans);
            }
            if(opt == 4)
            {
                LL ans = query2(1,1,n,l,r);
                printf("%lld
    ",ans);
            }
        }
        return 0;
    T1
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-')f = -f;
        for(;isdigit(ch);x = 10 * x + ch - '0',ch = getchar());
        return x * f; 
    }
    int n,ac,ans;
    int cr[1010],cc[1010];
    char ch[1010];
    int main()
    {
        n = read();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch + 1);
            for(int j=1;j<=n;j++)
            {
                if(ch[j] == '#')ac++;
                if(ch[j] == '.')cr[i] ++,cc[j]++;
            }
        }
        if(!ac){puts("-1");return 0;}
        for(int i=1;i<=n;i++)if(cc[i])++ans;
        int _Ma = 2 * n + 1;
        for(int i=1;i<=n;i++)_Ma = min(_Ma,cr[i] + (cc[i] == n));
        cout<<ans + _Ma<<endl;
    }
    T2
    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int LIM = 555;
    inline int read()
    {
        int x=0,f=1;char ch;
        for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f=-f;
        for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
        return x*f;
    }
    const int maxn = 210010;
    int n,m,k,q;
    char s[maxn];
    struct SAM
    {
        int tr[maxn][26],fa[maxn],len[maxn],size[maxn];
        int ST[maxn][21],id[maxn],Cnt[maxn];
        int last,p,np,q,nq,cnt,rt;
        SAM(){last = ++cnt; rt = 1;}
        inline void extend(int c)
        {
            p = last, np = last = ++cnt, len[np] = len[p] + 1;size[np] = 1;
            while(!tr[p][c] && p) tr[p][c] = np, p = fa[p];
            if(!p) fa[np] = rt;
            else
            {
                q = tr[p][c];
                if(len[q] == len[p] + 1) fa[np] = q;
                else
                {
                    nq = ++cnt; len[nq] = len[p] + 1; memcpy(tr[nq],tr[q],sizeof(tr[q]));
                    fa[nq] = fa[q]; fa[q] = fa[np] = nq;
                    while(tr[p][c] == q) tr[p][c] = nq,p = fa[p];
                }
            }
        }
        inline void buildsize()
        { 
            for(int i=1;i<=cnt;i++)Cnt[len[i]]++;
            for(int i=1;i<=n;i++)Cnt[i] += Cnt[i-1];
            for(int i=1;i<=cnt;i++)id[Cnt[len[i]]--] = i;
            for(int i=cnt;i>=1;i--)size[fa[id[i]]] += size[id[i]];
        }
        inline void STLCA()
        {
            for(int i=1;i<=cnt;i++)ST[i][0]=fa[i];
            for(int i=1;i<21;i++)for(int j=1;j<=cnt;j++)ST[j][i]=ST[ST[j][i-1]][i-1];
        }
        inline int query(int x,int va)
        {
            if(len[x] < va)return 0;
            for(int i=20;i>=0;i--)
                if(len[ST[x][i]] >= va)x = ST[x][i];
            return size[x];
        }
        inline int trans(int &now,int v,int x)
        {
            if(tr[now][x])
            {
                now=tr[now][x];
                return v + 1;
            }
            while(now && !tr[now][x])now=fa[now];
            v = len[now];
            if(tr[now][x])v++;
            now = tr[now][x];
            if(now == 0)now = 1;    
            return v;
        }
    }sam;
    //快来跟我写后缀自动机 写一下 调一年
    struct Xianzhi{int l,r;}req[maxn];
    namespace Modui_ksmall
    {
        struct Query
        {
            int l,r,id;
            bool operator < (const Query &a)const
            {
                if((l / LIM) == (a.l / LIM))return r < a.r;
                return (l / LIM) < (a.l / LIM);
            }
        }qs[maxn];
        LL res[maxn],ans[LIM][LIM];
        char w[maxn][LIM];
        void solve()
        {
            for(int i=1;i<=q;i++)
            {
                scanf("%s",w[i] + 1);
                qs[i].l = read() + 1;qs[i].r = read() + 1;qs[i].id = i;
            }
            sort(qs + 1,qs + q + 1);
            int l = 0,r = 0;
            for(int i=1;i<=q;i++)
            {
                for(;l < qs[i].l;l++)ans[req[l].l][req[l].r]--;
                for(;l > qs[i].l;l--)ans[req[l - 1].l][req[l - 1].r]++;
                for(;r < qs[i].r;r++)ans[req[r + 1].l][req[r + 1].r]++;
                for(;r > qs[i].r;r--)ans[req[r].l][req[r].r]--;
                for(int s=1;s<=k;s++)
                {
                    int now = 1;
                    for(int t=s;t<=k;t++)
                    {
                        now=sam.tr[now][w[qs[i].id][t] - 'a'];
                        if(now)res[qs[i].id] += (LL) sam.size[now] * ans[s][t]; 
                    }
                }
            }
            
            for(int i=1;i<=q;i++)printf("%lld
    ",res[i]);
        }
    }
    namespace Beizeng_klarge
    {
        vector<LL> vec[maxn];
        char w[maxn];
        int v;
        void solve()
        {
            LL ans;int a,b;
            while(q--)
            {
                ans = 0;
                scanf("%s%d%d",w + 1,&a,&b);a++,b++; 
                for(int i=a;i<=b;i++)vec[req[i].r].push_back(req[i].r - req[i].l + 1);
                int now = 1,maxlen = 0;
                for(int i=1;i<=k;i++)
                {
                    maxlen = sam.trans(now,maxlen,w[i] - 'a');
                    for(auto j : vec[i])
                        if(maxlen >= j)ans += sam.query(now,j);
                    vec[i].clear(); 
                }
                printf("%lld
    ",ans);
            } 
        }
    }
    
    int main()
    {
        n = read(),m = read(),q = read(),k = read();
        scanf("%s",s + 1);for(int i=1;i<=n;i++)sam.extend(s[i] - 'a');
        sam.buildsize(),sam.STLCA();
        for(int i=1;i<=m;i++)req[i].l = read() + 1,req[i].r = read() + 1;
        if(k < LIM)Modui_ksmall::solve();
        else Beizeng_klarge::solve();
    }
    T3_C++11
  • 相关阅读:
    mysql数据库题目【杭州多测师】【杭州多测师_王sir】
    python题目:维度为(M,N)求矩阵的转置【杭州多测师】【杭州多测师_王sir】
    python题目【杭州多测师】【杭州多测师_王sir】
    购物车测试点【杭州多测师】【杭州多测师_王sir】
    史上最全软件测试工程师常见的面试题总结【杭州多测师】【面试题】【杭州多测师_王sir】
    查询"001"课程比"002"课程成绩高的所有学生的学号【杭州多测师】【杭州多测师_王sir】
    mysql数据库查询当天,最近7天,最近1个月数据【杭州多测师】【杭州多测师_王sir】
    python题目:判断一个IP地址是否合法【杭州多测师】【杭州多测师_王sir】
    sql floor()函数
    mysql左连右连
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9141443.html
Copyright © 2020-2023  润新知