总结

周训练总结

J - Soldier and Number Game

Two soldiers are playing a game. At the beginning first of them
chooses a positive integer n and gives it to the second soldier. Then
the second one tries to make maximum possible number of rounds. Each
round consists of choosing a positive integer x > 1, such that n is
divisible by x and replacing n with n / x. When n becomes equal to 1
and there is no more possible valid moves the game is over and the
score of the second soldier is equal to the number of rounds he
performed.

To make the game more interesting, first soldier chooses n of form
a! / b! for some positive integer a and b (a ≥ b). Here by k! we
denote the factorial of k that is defined as a product of all positive
integers not large than k.

What is the maximum possible score of the second soldier?

Input First line of input consists of single integer t
(1 ≤ t ≤ 1 000 000) denoting number of games soldiers play.

Then follow t lines, each contains pair of integers a and b
(1 ≤ b ≤ a ≤ 5 000 000) defining the value of n for a game.

Output For each game output a maximum score that the second soldier
can get.

Examples Input 2 3 1 6 3 Output 2 5\

这一题大致意思是求两个数(a,b]之间的质因子数之和
我一开始便用暴力求解法

void ok(ll x){
ll ans=0,x1=x;
for( ll i=2;i<=x;i++)
if(x%i==0)
{
ans++;
x/=i;
i--;
}
prs[x]=prs[x-1]+ans;
}
int main()
{
for(ll i=2;i<=5000000;i++)
ok(i);
}

我试着运行了一下十几秒还没出来,所以我又重新想了一下这个解法需要每个数都要搜索判断基于5000000耗时太大,这题是求质因子,每个数等于其所有质因子之积,所以能否列出所有的质子,找到它们的倍数然后处理;,但是列出质子是个问题,用了粗暴的方法,果不其然又超时了。因为质子的因子只有两个。所以我们先从2开始列举数,只要fo[i]不为零它就一定不是质数。这样就可以省去很多步骤和时间了。

void ok1()
{
    for(int i=2;i<=5000000;i++)
        if(!fo[i])//判断是否为质数
        for(int j=i;j<=5000000;j+=i)
            fo[j]=fo[j/i]+1;//一个数除以质数得到数的质因子个数加上这个质数个数
}

最后因测试个数过多用scanf printf 替代 cin cout

Sasha and a Bit of Relax

Sasha likes programming. Once, during a very long contest, Sasha
decided that he was a bit tired and needed to relax. So he did. But
since Sasha isn’t an ordinary guy, he prefers to relax unusually.
During leisure time Sasha likes to upsolve unsolved problems because
upsolving is very useful.

Therefore, Sasha decided to upsolve the following problem:

You have an array a with n integers. You need to count the number of
funny pairs (l,r) (l≤r). To check if a pair (l,r) is a funny pair,
take mid=l+r−12, then if r−l+1 is an even number and
al⊕al+1⊕…⊕amid=amid+1⊕amid+2⊕…⊕ar, then the pair is funny. In other
words, ⊕ of elements of the left half of the subarray from l to r
should be equal to ⊕ of elements of the right half. Note that ⊕
denotes the bitwise XOR operation.

It is time to continue solving the contest, so Sasha asked you to
solve this task.

Input The first line contains one integer n (2≤n≤3⋅105) — the size of
the array.

The second line contains n integers a1,a2,…,an (0≤ai<220) — array
itself.

Output Print one integer — the number of funny pairs. You should
consider only pairs where r−l+1 is even number.

这道题得知是亦或算法且al⊕al+1⊕…⊕amid=amid+1⊕amid+2⊕…⊕ar,容易知道从左到右亦或为零,但数据数目为十的20次方,确定零区间不大可能。所以,需从亦或其他方面下手。因为0^ a=a.所以an ^ an+1 ^ …an+n=a1 ^ a2 … ^ an+n ^ ( a1 ^ a2 … ^ an-1) = 0^ 原式=原式;所以题目条件可变为
XOR(1,l-1) ^ XOR(1,mid) == XOR(1,mid) ^ XOR(1,r) 约去得 XOR(1,l-1)=XOR(1,r);这就可以遍历找相同结果的点了。题目还要求r-l+1为偶数,常理知奇数-奇数,偶数减偶数,都是偶数,所以建立一个二维数组判断坐标奇偶,存入结果,找前面满足条件的点数,但是在测试例子时遇到一种特殊情况-----------结果有时只有一个零但符合条件,测试了许多数据,得知n为偶数时满足条件所以初始化dp[0][0]=1;
源代码

#include<iostream>
using namespace std;
long long  dp[2][10000005];
int main()
{   dp[0][0]=1;
    long long  k,g,p=0,ans=0;
    cin>>k;
    for(long long  i=1;i<=k;i++)
    {
        cin>>g;
        p^=g;
        ans+=dp[1&i][p];
        dp[1&i][p]++;
    }
    cout<<ans<<endl;
}

E - Kyoya and Colored Balls

Kyoya Ootori has a bag with n colored balls that are colored with k
different colors. The colors are labeled from 1 to k. Balls of the
same color are indistinguishable. He draws balls from the bag one by
one until the bag is empty. He noticed that he drew the last ball of
color i before drawing the last ball of color i + 1 for all i from 1
to k - 1. Now he wonders how many different ways this can happen.

Input The first line of input will have one integer k (1 ≤ k ≤ 1000)
the number of colors.

Then, k lines will follow. The i-th line will contain ci, the number
of balls of the i-th color (1 ≤ ci ≤ 1000).

The total number of balls doesn’t exceed 1000.

Output A single integer, the number of ways that Kyoya can draw the
balls from the bag as described in the statement, modulo
1 000 000 007.

题目大意,有n种颜色数量一的小球,如果第i种排完后,它的后一位一定是第i+1种小球,那么有多少种排列方式呢?
这题很明显是运用动态规划,看测试数据无思路后,我便草拟了排序方式,当第1种球排序时显然只有一种,第二个球排序时要满足最后一个球在最后,并且至少有一个球在第二个球前面,那么变成了sum-1个球排序c(n2-1,sum-1);然后第三个球加入时排序便是在前面排序中加入n3-1个球,所以排序为c(n2-1,sum-1)*c(n3-1,sum-1);其余的类似,c(n-1,sum-1)便是杨辉三角可用dp,dp[i][j]=dp[i][j-1]+dp[i-1][j-1];整理出dp打表即可。
源代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 2000000+5
#define maxx 0x3f3f3f3f
#define R 1000000007
typedef long long ll;
ll scan_d()
{
    char t=getchar();ll you=0;
    while(t>'9'||t<'0')t=getchar();
    while(t<='9'&&t>='0'){you*=10;you+=t-'0';t=getchar();}
    return you;
}
ll dp[1050][1050];
ll op[1001];
int main()
{
    for(int i=0;i<=1010;i++)
    dp[1][i]=1;
    for(int i=2;i<=1010;i++)
        for(int o=i-1;o<=1010;o++)
        {dp[i][o]=dp[i-1][o-1]+dp[i][o-1];dp[i][o]%=R;}
      ll y;y=scan_d(); ll sum=0;
     for(int i=1;i<=y;i++)
       {op[i]=scan_d();}
        ll ans=1;
      for(int i=1;i<=y;i++)
      {
          sum+=op[i];
          ans*=dp[op[i]][sum-1];
          ans%=R;
      }
      cout<<ans<<endl;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值