Codeforces Round #520 (Div. 2)

https://codeforces.com/contest/1062

https://codeforces.com/contest/1062/problem/B

题意 :
给一个数字n
有两种操作
n 乘上任意一个数字
n变成根号n (根号n必须是整数, 就是 n必须是某个数字的平方)

然后 问n能变成最小值的最少操作

题解:

把n进行质因数分解 ,并且数每个质因数的数量
然后检查最大次幂是多少 如果质因数数量有不同的话就让最大次幂加一 否则的话不加

原因就是 我们可以乘上任意的一个数字 所以我们一次性就可以补足所有次幂
比如 2 2 2 2 2 2 3 3 3 3 乘上 2 2 3 3 3 3 然后开跟3 次
就变成了 2 3
这是质因数情况的展示

#include
using namespace std;
int main()
{
    int n;
    while ( cin >> n )
    {
        vector arr;
        int mins = 1;
        for ( int i = 2; i <= n; i++ )
        {
            int ans = 0;
            while ( n % i == 0 )
            {
                n /= i;
                // cout< power )
            {
                power *= 2;
                num++;
            }
        }
        int ans = 0;
        for ( int i = 0; i < arr.size(); i++ )
        {
            ans = ans | ( power != arr[i] );
        }

        cout << mins << ' ' << ans + num << endl;
    }
}

https://codeforces.com/contest/1062/problem/C

题意:
一个人喜欢吃一种食物,
然后 这一天 ,他想以一种诡异的方式享受这种食物
他把食物分成了n块
每块的美味度定义为0或者1

然后 他吃的时候 吃掉的那块的美味度会增加到其它所有块身上,
比如 010 吃掉中间的1 就变成 1 _ 1 然后随便吃个1 就变成了 _ _2 然后再吃掉,
就是他能享受数值为4的美味度了

然后 就是扯淡的地方了
他想知道他自己吃某个连续区间的时候 最大享受值是多少,他不一定想吃完那种食物。

然后输入一个n 代表n块,
之后输入一行01串
然后输入询问 每次询问都是一个区间
输出的是享受的最大美味度

思考 :
因为边做边想边敲代码 - -
我首先发现 一串01串的最大值是固定的 和0 的数量还有1的数量有关系
比如 010 和 100 和 001 是一样的- -
然后 举个例子 1010
首先吃个1 变成了 _121 想想 这时候吃二肯定最好啊 因为 这样的话能让其它位置都加上2
所以 每次吃最大的 最后吃完的总和是最大的。

test写完了就能慢慢刷题了 真舒服- - 咋写 - -然后咋写- - 还有算法没有push到master上- -
年前学会的git给失忆了- - 明天就周末了- -

还有三道题- -

找规律 找 01 数量的规律 = =

全1情况每次增加 1 2 4 8 这样的规律
然后 0的位置增加最大数减1 比如1111000 是 1 2 4 8 15 30 60 所以规律找到了- -
所以这是个数学题

等比数列公式 百度一下 回忆起来

在这里插入图片描述
在这里插入图片描述
第一步 公比为 2 ,a1=1 数目1 的数量 为x
s1 = (1-2^x) /-1 = 2^x-1 ;
第二部 公比为2 然后此时0 位置上的大小刚刚好是 s1 没问题吧 因为最后的1 的最后的和就是s1

s2= s1*(1-2^y)/-1 =2^y*s1-s1;

和为s1+s2;

#include 
using namespace std;
const long long  maxn = 1e5 + 5;
long long  x[maxn], y[maxn];
const long long  mod = 1e9 + 7;
unsigned long long power ( unsigned long long x, unsigned long long y, unsigned long long mod )
{
    long long  t = x, ans = 1;
    while ( y )
    {
        if ( y % 2 )
            ans = ( ans * t ) % mod;
        y /= 2;
        t = t * t % mod;
    }
    return ans;
}
int main()
{
    long long  n, m;
    while ( cin >> n >> m )
    {
        memset ( x, 0, sizeof ( x ) );
        memset ( y, 0, sizeof ( y ) );
        string s;
        cin >> s;
        for ( unsigned long long i = 0; s[i]; i++ )
        {
            if ( s[i] == '1' )
            {
                x[i + 1] = 1;
            }
            else
            {
                y[i + 1] = 1;
            }

            x[i + 1] += x[i];
            y[i + 1] += y[i];
        }

        long long  len = s.size();
        long long  left, right, a, b;
        for ( unsigned long long i = 1; i <= m; i++ )
        {
            cin >> left >> right;
            a = x[right] - x[left - 1];
            b = y[right] - y[left - 1];
            // cout<<"asd   "<
#include 
using namespace std;
const long long  maxn = 1e5 + 5;
long long  x[maxn], y[maxn];
const long long  mod = 1e9 + 7;
long long power (  long long x,  long long y, long long mod )
{
    long long  t = x, ans = 1;
    while ( y )
    {
        if ( y % 2 )
            ans = ( ans * t ) % mod;
        y /= 2;
        t = t * t % mod;
    }
    return ans;
}
int main()
{
    long long  n, m;
    while ( cin >> n >> m )
    {
        x[0]=y[0]=0;
        string s;
        cin >> s;
        for ( int i = 0; s[i]; i++ )
        {
            x[i + 1] = x[i] + ( s[i] == '1' );
            y[i + 1] = y[i] + ( s[i] == '0' );
        }
        long long  len = s.size(), left, right, a, b;
        for ( int  i = 1; i <= m; i++ )
        {
            cin >> left >> right;
            a = x[right] - x[left - 1];
            b = y[right] - y[left - 1];
            long long  s1 = ( power ( 2, a, mod ) - 1 + mod ) % mod;
            long long  s2 = ( power ( 2, b, mod ) * ( s1 ) % mod - ( s1 ) + mod ) % mod;
            cout << ( s1 + s2 ) % mod << endl;
        }

    }
}

https://codeforces.com/contest/1062/problem/D
补题520场 = = 还是认真点 - -

题意:
首先 意思就是 给个n 这个n 呢 每次给两个数字 a 和b 并且a和b 要大于2
然后呢 找到一个x ax==b || bx==a 的时候 分数就加上x

然后 给出一个n
求分数。

题解:
慢慢想 首先,我们看到了4

2→4→(−2)→(−4)→2
这是给出的 答案是8
然后想想3 只有1 和 3 嘛 所以 3 是0
然后 5 , 5是 1和5 还是 0 所以 5 应该还是8
然后 6 , 6 就很6了 。
首先是 2—> 6 ->-2->-6->2 增加了12
然后是 3->6->-3->-6->3 增加了8
所以数字6 增加了20
然后 第二个样例是28
这时候就终于读懂题了- -
然后 递增的结果
每次只需要考虑 因数相乘等于n的情况 。

然后想想- - 边想边写题解- -
暴力解法就是 寻找每个n
然后枚举所有的不同的因数相乘- -
如果每个n寻找因子的复杂度是 根号n次 每次计算复杂度是根号n 然后 十万个加起来- -
试试- - 万一对了 。
肯定要写个预处理 - -。预处理下前缀和一样的玩意 然后o(1)输出。

卧槽 对了 ;
要注意下longlong int 会爆炸

#include 
using namespace std;
const long long maxn = 1e5 + 5;
long long sum[maxn];
void run()
{
    sum[3] = 0;
    for ( long long i = 4; i < maxn; i++ )
    {
        long long len = sqrt ( i );
        long long ans = 0;
        for ( long long j = 2; j <= len; j++ )
        {
            if ( i % j == 0 )
            {

                long long a = j, b = i / j;
                if ( a != b )
                {
                    ans += 4 * ( a + b );
                    // cout<

你可能感兴趣的:(CF刷题日记)