zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 81 (Rated for Div. 2)

    A~Dhttps://www.cnblogs.com/GoodVv/p/12249839.html

    因为懒所以 A ~ D 拿给VV写了 ʅ(‾◡◝)ʃ

    但是我的代码还是会放上的(思路可能和VV博客里写的不一样)

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int t;
        cin >> t;
        while(t --)
        {
            int n ;
            cin >> n;
            if(n & 1) cout << 7 , n -= 3;
            for(int i = 1 ; i <= n / 2 ; i ++) cout << 1;
            cout << '
    ';
        }
        return 0;
    } 
    A - Display The Number
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    map<ll , ll>cnt;
    ll n , x , ans , sum;
    string s;
    int main()
    {
        ll t;
        cin >> t;
        while(t --)
        {
            cnt.clear();
            ans = sum = 0; 
            cin >> n >> x >> s;
            if(x == 0) ans = 1;
            for(auto i : s)
            {
                if(i - '0') sum --;
                else           sum ++;
                cnt[sum] ++;
            }
            if(!sum)
            {
                if(!cnt[x]) cout << 0 << '
    ';
                else         cout << -1 << '
    ';
                continue ;
            }
            for(auto it : cnt)
                if(abs(it.first - x) % (sum) == 0)
                {
                    if((x > it.first && sum < 0) || (x < it.first && sum > 0)) continue;
                    ans += it.second;
                }
            cout << ans << '
    ';
        }
        return 0;
    } 
       
    B - Infinite Prefixe
    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    const int N = 1e5 + 10;
    int pos[N][27];
    char s[N] , t[N];
    int main()
    {
        int T;
        cin >> T;
        while(T --)
        {
            cin >> s + 1 >> t + 1;
            int len1 = strlen(s + 1) , len2 = strlen(t + 1);
            for(int j = 0 ; j < 26 ; j ++) pos[len1][j] = inf;
            for(int i = len1 - 1; i >= 0 ; i --)
            {
                for(int j = 0 ; j < 26 ; j ++)
                    pos[i][j] = pos[i + 1][j];
                pos[i][s[i + 1] - 'a'] = i + 1;
            }
            int now = 1 , flag = 1 , ans = 0;
            while(now <= len2)
            {
                if(pos[0][t[now] - 'a'] == inf) { flag = 0 ; break ; }
                int idx = pos[0][t[now] - 'a'];
                while(idx != inf && now <= len2)
                now ++ , idx = pos[idx][t[now] - 'a'];
                ans ++ ;
            }
            if(!flag) cout << -1 << '
    ';
            else cout << ans << '
    ';
        }
        return 0;
    }
    C - Obtain The String
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 2e5 + 10;
    ll eular(ll n)
    {
        ll ans = n;
        for(ll i = 2; i * i <= n ; i ++)
        {
            if(n % i == 0)
            {
                ans = ans / i * (i - 1);
                while(n % i == 0)
                    n /= i;
            }
        }
        if(n > 1) ans = ans / n * (n - 1);
        return ans;
    }
    int main()
    {
        int t;
        cin >> t;
        while(t --)
        {
            ll a , b;
            cin >> a >> b;
            ll gcdd = __gcd(a , b);
            b /= gcdd;
            cout << eular(b) << '
    ';
        }
        return 0;
    }
     
    D - Same GCDs

    E. Permutation Separation

    题目链接:https://codeforces.com/contest/1295/problem/E

    题意:

      给你一个长度为n的数组,其中 1 ~ n 每个数恰好在该数组中出现一次,并且每个数都有自己的价值 ai

      你要在数组中任意位置切一刀使数组划分为左集合和右集合(刚切完左右集合不得为空)

      切完后你可以将一个集合的任意一个元素 x 丢到另一个集合去,但是你需要支付 a[x]的代价

      现要使操作结束后右集合的元素均大于左集合的元素(或其中任意一集合为空集),问你最小代价是多少

    分析:

      先模拟一遍

      假设 n = 6,数组的元素分别为 3,6,5,4,1,2 ,那么我们可以切的位置分别有3,6、6,5、5,4、4,1、1,2之间

      我们将每一个可以切的间隙从左往右进行编号,并定义为切点,如图所示:

      其中 1 左边的切点有①②③④,右边的切点有⑤

      2 左边的切点有①②③④⑤,右边没有切点

      3 左边没有切点,右边的切点有①②③④⑤

      ......

      在开始之前,我们还要知道当我们操作完之后,左集合要么为空,要么剩余 m 个元素,而剩余的元素分别是1 ~ m

      好了在了解完以上后,我们采用边枚举边更新的方法

      首先,让我们用pos[i] 表示第 i 个元素的位置,其中pos[1] = 5,pos[2] = 6,pos[3] = 1...

      用sum[i] 表示前 i 个位置的代价前缀和,其意义是将切点 i 左边的数全移至右边所付出的代价

      初始我们先让第 i 个切点的代价为sum[i] , 即在切完之后将左边所有数都移至右集合。

      我们用线段树维护每个切点的花费(第 i 个位置(区间)维护第 i 个切点),然后我们开始对每个元素进行枚举

      one首先是元素 1  , pos[1] = 5 , 我们观察第五个元素右边的切点有⑤ , 左边的切点有①②③④

      对于右边的切点⑤:它当前的花费为sum[5] ,包括了元素1的代价,但实际上在切完⑤之后元素1在左集合,且我们并不需要把元素1移至右边,所以我们把切点⑤的花费减去元素1的代价

      对于左边的切点:在切完之后元素1是处于集合的右边,所以开始的时候sum[1],sum[2],sum[3],sum[4]并没有算上元素1右移的代价

      而实际上元素1应该要移至左集合,所以我们把切点①~④的花费加上元素1的代价

      two然后是元素2, pos[2] = 6 , 第六个元素右边没有切点,左边的切点有①②③④⑤

      对于右边的切点:无。

      对于左边的切点:切完之后元素2是处于集合的右边,所以开始的时候sum[1],sum[2],sum[3],sum[4],sum[5]并没算上元素2右移的代价

      而实际上元素2应该要移至左集合,所以我们把切点①~⑤的花费加上元素2的代价

      three紧接着是元素3,pos[3] = 1,第一个元素的左边没有切点,右边的切点有①②③④⑤

      对于右边的切点:在切完之后元素3是处于集合的左边,且我们并不需要把元素3右移。

      但在初始的时候我们统一把左集合的全都右移了,所以初始的时候切点①②③④⑤的花费都算上元素3的代价,所以我们要把他们的花费减去元素3的代价

      对于左边的切点:无。

      ......

      根据以上我们发现,对于第 i 次枚举(元素 i )编号为 1 ~ pos[i] - 1 的切点(元素 i 的右边)花费都要减去 i 的代价,而编号 pos[i] ~ n - 1的切点(元素i的左边)花费都要加上 i 的代价

      这只要用线段树区间更新一波就可以把复杂度降至 logn,在加上枚举的时间消耗,总复杂度为 nlogn . 完全OK

      ans 的值我们在每次枚举完更新

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    const int N = 2e5 + 10;
    struct Segment_Tree{
        ll l , r;
        ll minn , lazy;
    }tree[N << 2];
    void build(ll l , ll r , ll rt , ll *aa)
    {
        tree[rt].l = l , tree[rt].r = r;
        if(l == r)
        {
            tree[rt].minn = aa[l];    
            return ;
        }
        ll mid = l + r >> 1;
        build(l , mid , rt << 1 , aa);
        build(mid + 1 , r , rt << 1 | 1 , aa);
        tree[rt].minn = min(tree[rt << 1].minn , tree[rt << 1 | 1].minn);
    }
    void push_down(ll rt)
    {
        if(tree[rt].lazy)
        {
            tree[rt].minn += tree[rt].lazy;
            tree[rt << 1].minn += tree[rt].lazy;
            tree[rt << 1 | 1].minn += tree[rt].lazy;
            tree[rt << 1].lazy += tree[rt].lazy;
            tree[rt << 1 | 1].lazy += tree[rt].lazy;
            tree[rt].lazy = 0;
        }
    } 
    void update_range(ll L , ll R , ll val , ll rt)
    {
        if(tree[rt].r < L || tree[rt].l > R) return ;
        if(L <= tree[rt].l && R >= tree[rt].r)
        {
            tree[rt].lazy += val;
            tree[rt].minn += val;
            return ;
        }
        push_down(rt);
        ll mid = tree[rt].l + tree[rt].r >> 1;
        if(L <= mid)
        update_range(L , R , val , rt << 1);
        if(R > mid)
        update_range(L , R , val , rt << 1 | 1);
        tree[rt].minn = min(tree[rt << 1].minn , tree[rt << 1 | 1].minn);
    }
    ll query_min(ll L , ll R , ll rt)
    {
        if(L <= tree[rt].l && R >= tree[rt].r)
        return tree[rt].minn;
        push_down(rt);
        ll mid = tree[rt].l + tree[rt].r >> 1;
        ll res1 = (0x3f3f3f3f3f3f3f3fll) , res2 = (0x3f3f3f3f3f3f3f3fll);
        if(L <= mid)
        res1 = query_min(L , R , rt << 1);
        if(R > mid)
        res2 = query_min(L , R , rt << 1 | 1);
        return min(res1 , res2);
    }
    ll a[N] , pos[N] , sum[N];
    int main()
    {
        int n ;
        cin >> n;
        for(int i = 1 ; i <= n ; i ++)
        {
            int x ; cin >> x;
            pos[x] = i;
        }
        for(int i = 1 ; i <= n ; i ++)
        cin >> a[i] , sum[i] = sum[i - 1] + a[i];
        build(1 , n - 1 , 1 , sum);
        ll ans = min(a[1] , a[n]);
        for(int i = 1 ; i <= n - 1 ; i ++)
        {
            update_range(pos[i] , n - 1 , -a[pos[i]] , 1);
            update_range(1 , pos[i] - 1 , a[pos[i]] , 1);
            ans = min(ans , query_min(1 , n - 1 , 1));
        }
        update_range(pos[1] , n - 1 , -a[pos[1]] , 1);
        update_range(1 , pos[i] - 1 , a[pos[1]] , 1);
        cout << ans << '
    ';
        return 0;
    }
    凡所不能将我击倒的,都将使我更加强大
  • 相关阅读:
    C# List对象集合重组为新集合和获取某个字段组成新数组
    sqlserver xml for path html标签被转译问题
    高中信息技术(Python)重难点3:最大公约数
    高中信息技术(Python)重难点2:编码
    高中信息技术(Python)重难点1:数制
    天天快乐编程监考系统使用文档
    2021年OI集训队赛前模拟5题解
    2021年OI集训队赛前模拟4题解
    mysql-shell部署MGR
    GreatSQL手工部署mgr集群
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/12249128.html
Copyright © 2011-2022 走看看