• CodeForces round 520 div2


    A:A Prank

    题意:给定一个递增序列, 问最多能删除多少个连续数字,要求删除数字之后能还原成原来的数列。

    题解:直接找就好了,为了方便可以使得第0个数字为0, 第n+1个元素为1001

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    int a[N];
    int main(){
        int n, m = 0;
        scanf("%d", &n);
        a[0] = 0, a[n+1] = 1001;
        for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        int ans = 0;
        for(int i = 1; i <= n; ++i){
            if(a[i-1]+1 == a[i] && a[i]+1 == a[i+1]) m++;
            else m = 0;
            ans = max(ans, m);
        }
        cout << ans << endl;
        return 0;
    }
    View Code

    B:Math

    题意:给你一个n,现在有2种操作,1把这个n乘上一个值,2把这个n开根号,要求开完根号之后还是整数,求n最小能变成多少,以及最小的操作次数。

    题解:对于一个数字,我们先把他分解质因子,计算每个因子的个数,很明白,只有所有的质因子都为偶数的时候,他这个时候才能开方,

    并且,这个数的最小值就是这些不同的质因子的乘积。

    要使数字变小,所以我们先需要把每个因子的个数都变成偶数,然后在开根号,因子个数都会/2

    所以我们需要找到最大的因子个数是啥,假如为x,然后把所有数目都变成 x <= 2^k 次,然后我们只需要一直开方就好了。

    如果x = 5, 我们至少要把除3次,为了避免每次都需要先乘上一个数,我们把第一次乘法的时候就把他变成2^k。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    vector<int> vc;
    int aaans = 1;
    void solve(int x){
        for(int i = 2; i*i <= x; ++i){
            if(x%i == 0){
                int cnt = 0;
                aaans *= i;
                while(x%i == 0){
                    x /= i;
                    cnt++;
                }
                vc.pb(cnt);
            }
        }
        if(x != 1) vc.pb(1);
        aaans *= x;
    }
    int cnt = 0;
    
    int main(){
        int n;
        scanf("%d", &n);
        solve(n);
        if(vc.size() == 0) vc.pb(1);
        int mx = 0, f = 0;
        for(auto v : vc){
            mx = max(v, mx);
        }
        int tmp = 0;
        for(int i = 0;;++i){
            if(mx <= (1<<i)){
                tmp = i;
                break;
            }
        }
        int ans = tmp;
        tmp = 1 << tmp;
        for(auto v: vc){
            if(tmp != v) f = 1;
        }
        ans += f;
        cout << aaans << ' ' << ans << endl;
        return 0;
    }
    View Code

    C:Banh-mi

    题解:找规律。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL mod = (int)1e9+7;
    const int N = 1e5 + 100;
    int cnt[N][2];
    LL dp[N];
    void init(){
        //LL t = 1;
        dp[1] = 1;
        for(int i = 2; i < N; ++i){
            dp[i] = dp[i-1]<<1;
            if(dp[i] > mod) dp[i] -= mod;
        }
    }
    int solve(int x, int y){
        LL ret = 0;
        ret = dp[y+1] - 1;
        ret += (dp[y+1]-1)*(dp[x+1]-1);
        ret = ((ret%mod)+mod)%mod;
        return ret;
    }
    char s[N];
    int main(){
        int n, q;
        init();
        scanf("%d%d", &n, &q);
        scanf("%s", s+1);
        for(int i = 1; i <= n; ++i){
            cnt[i][0] = cnt[i-1][0];
            cnt[i][1] = cnt[i-1][1];
            cnt[i][s[i]-'0']++;
        }
        int l, r;
        while(q--){
            scanf("%d%d", &l, &r);
            printf("%d
    ", solve(cnt[r][0]-cnt[l-1][0],cnt[r][1]-cnt[l-1][1]));
        }
        return 0;
    }
    View Code

    D:Fun with Integers

    题解:我们可以从样例分析中发现,我们可以经过4次跳跃之后返回到原来的这个地方。

    也就是说,我们每次走到一个新的位置之后,我们可以遍历他的所有因子,再返回到这个位置,然后继续按原来的路径行事。

    我们不用管他怎么走,只需要明白每出现一个数会对答案产生什么影响就好了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    int vis[N];
    void init(){
        for(int i = 2; i < N; ++i){
            for(int j = i+i, t = 2; j < N; j+=i, t++){
                    vis[j] += t;
            }
        }
    }
    int main(){
        int n;
        scanf("%d", &n);
        init();
        LL sum = 0;
        for(int i = 2; i <= n; ++i){
            sum += vis[i];
        }
        cout << sum*4 << endl;
        return 0;
    }
    View Code

    E:Company

    题意:求多个点 在可以删除一个点的前提下剩下的点lca 取 深度最大的点能是啥。

    题解:我们把树建立起来,跑一遍dfs,记录下他的dfs序。

    那么答案就是找到这个区间的 最大值dfs序, 次大值, 次小值, 最小值。

    然后答案就是在删除最大值的位置下 和 删除最小值的位置下取优。

    这个操作是基于一个思想,就是 这些点的lca就是 dfs序的最大值的那个位置 和 最小值的那个位置的lca。

    原因很简单,我们需要找到一个点 他的dfs序 入和出 能包括询问的所有的dfs序。

    也就是说找到一个点  in[v] <= min(q - point )  out[v] >= max( q - point)

    观察上式,我们发现只有 最大值和最小值发生了改变才会对答案产生影响, 删除中间的点是不会产生影响的。

    所以我们只需要找到 最大值, 次大值, 次小值, 最小值 然后删除最大值 查询最小值和次大值的lca 和 删除最小值查询次小值和最大值的lca 2者取优就好了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    int anc[N][20];
    int dfn[N], now = 0, deep[N], pos[N];
    int n, q;
    vector<int> vc[N];
    void dfs(int u){
        dfn[u] = ++now;
        pos[now] = u;
        for(auto v : vc[u]){
            deep[v] = deep[u] + 1;
            anc[v][0] = u;
            for(int i = 1; i < 18; ++i) anc[v][i] = anc[anc[v][i-1]][i-1];
            dfs(v);
        }
    }
    int Find(int u, int v){
        if(deep[u] < deep[v]) swap(u,v);
        int x = deep[u] - deep[v];
        for(int i = 17; i >= 0; --i)
            if((x>>i)&1)
                u = anc[u][i];
        if(u == v) return u;
        for(int i = 17; i >= 0; --i)
            if(anc[u][i] != anc[v][i])
                u = anc[u][i], v = anc[v][i];
        return anc[v][0];
    
    }
    int tmx[N<<2], tmn[N<<2];
    void build(int l, int r, int rt){
        if(l == r){
            tmx[rt] = tmn[rt] = dfn[l];
            return ;
        }
        int m = l+r >> 1;
        build(lson); build(rson);
        tmx[rt] = max(tmx[rt<<1], tmx[rt<<1|1]);
        tmn[rt] = min(tmn[rt<<1], tmn[rt<<1|1]);
    }
    int Qmax(int L, int R, int l, int r, int rt){
        if(L > R) return 0;
        if(L <= l && r <= R) return tmx[rt];
        int m = l+r >> 1;
        int ret = 0;
        if(L <= m) ret = max(ret, Qmax(L,R,lson));
        if(m < R) ret = max(ret, Qmax(L,R,rson));
        return ret;
    }
    int Qmin(int L, int R, int l, int r, int rt){
        if(L > R) return N;
        if(L <= l && r <= R) return tmn[rt];
        int m = l+r >> 1;
        int ret = N;
        if(L <= m) ret = min(ret, Qmin(L,R,lson));
        if(m < R) ret = min(ret, Qmin(L,R,rson));
        return ret;
    }
    void solve(int l, int r){
        int x1, x2, x3, x4;
        int v1, v2, v3, v4;
        v1 = Qmax(l,r,1,n,1);
        x1 = pos[v1];
        v2 = max(Qmax(l,x1-1,1,n,1), Qmax(x1+1,r,1,n,1));
        x2 = pos[v2];
        v4 = Qmin(l,r,1,n,1);
        x4 = pos[v4];
        v3 = min(Qmin(l,x4-1,1,n,1), Qmin(x4+1,r,1,n,1));
        x3 = pos[v3];
        int ans1 = deep[Find(x1,x3)];
        int ans2 = deep[Find(x2,x4)];
        if(ans1 >= ans2)
            printf("%d %d
    ", x4, ans1);
        else printf("%d %d
    ", x1, ans2);
    }
    int main(){
        scanf("%d%d", &n, &q);
        for(int i = 2, u; i <= n; ++i){
            scanf("%d", &u);
            vc[u].pb(i);
        }
        dfs(1);
        build(1,n,1);
        int l, r;
        while(q--){
            scanf("%d%d", &l, &r);
            solve(l, r);
        }
        return 0;
    }
    View Code

    F:Upgrading Cities

    题意:问有多少个点是合法点,u点如果是合法点,则最多只有一个点v 是 u没法走到v, v没法走到u。 题目说了一开始的图不会是强连通图。

    题解:

    我们先正向建图,然后按照拓扑排序的写法,当一个点的度数为0的时候入队。

    每次我们取出一个点,我们看看队内是否为空,如果队内为空,则我们目前的这个点一定就是可以走到剩下图中所有的点。

    如果队内还有一个点, 首先我们需要明白, 已经取出来的点x 和 还在队内的那个点y 这2个点之间是没有边的关系的,即 x 不能走到 y, y不能走到x。

    现在我们判断一下,在剩下的图中,是不是有一个点是只能通过y走到的,如果存在这样的一个点,那么算上y之后就有2个点是x所不能走到了,那么x一定是非法点,所以我们不需要再精确的计算出x能到达多少点,这已经是没有意义的了。如果不存在一个点只能通过y走到,那么到目前为止,对于x来说只有y是没办法走到了,剩下图中的所有点都是可以走到的。

    当队内不止有一个点之后,我们通过上面的分析可以明白,x一定不会是合法点,因为已经至少有2个点不行了,同样的我们也不再需要计算x可以到多少个点。

    我们再反向建图,再按上面的程序跑一遍。

    最后我们把v能达到的点的数目和能到达v点的数目加起来,就可以判断这个点是不是合法点了。

    代码:

     

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL mod =  (int)1e9+7;
    const int N = 3e5 + 100;
    vector<int> vc[N];
    int u[N], v[N], d[N];
    int ans[N];
    int n, m;
    int sta[N];
    void bfs(){
        int tot = n;
        int l = 0, r = 0;
        for(int i = 1; i <= n; ++i)
            if(d[i] == 0){
                sta[r++] = i;
                tot--;
            }
        while(l < r){
            int x = sta[l++];
            if(l == r) ans[x] += tot;
            else if(l+1 == r){
                int y = sta[l], f = 1;
                for(auto v : vc[y]){
                    if(d[v] == 1){
                        f = 0;
                        break;
                    }
                }
                if(f) ans[x] += tot;
            }
            for(auto v : vc[x]){
                --d[v];
                if(d[v] == 0){
                    sta[r++] = v;
                    tot--;
                }
            }
        }
    
    }
    int main(){
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; ++i)
            scanf("%d%d", &u[i], &v[i]);
        for(int i = 1; i <= m; i++){
            vc[u[i]].pb(v[i]);
            ++d[v[i]];
        }
        bfs();
        for(int i = 1; i <= n; ++i)
            vc[i].clear();
        for(int i = 1; i <= m; ++i){
            vc[v[i]].pb(u[i]);
            ++d[u[i]];
        }
        bfs();
        int fans = 0;
        for(int i = 1; i <= n; ++i){
            fans += (ans[i] >= n-2);
        }
        printf("%d
    ", fans);
        return 0;
    }
    View Code
  • 相关阅读:
    Linux-nmap
    MongoDb注意事项
    HTML如何转XTML
    Centos 64位 Install certificate on apache 即走https协议
    CentOS 下搭建部署独立SVN服务器全程详解(5.5)
    LNMP安装与配置
    64位CentOS 6.0下搭建LAMP环境
    Apache遇到的问题:APR not found
    超详细LAMP环境搭建
    偏方治百病
  • 原文地址:https://www.cnblogs.com/MingSD/p/9967748.html
Copyright © 2020-2023  润新知