集训 before

来源:互联网 发布:2016网络流行词有哪些 编辑:程序博客网 时间:2024/06/01 08:48

C - Black Box

Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empty and i equals 0. This Black Box processes a sequence of commands (transactions). There are two types of transactions:

ADD (x): put element x into Black Box;
GET: increase i by 1 and give an i-minimum out of all integers containing in the Black Box. Keep in mind that i-minimum is a number located at i-th place after Black Box elements sorting by non- descending.

Let us examine a possible sequence of 11 transactions:

Example 1
N Transaction i Black Box contents after transaction Answer       (elements are arranged by non-descending)   1 ADD(3)      0 3   2 GET         1 3                                    3 3 ADD(1)      1 1, 3   4 GET         2 1, 3                                 3 5 ADD(-4)     2 -4, 1, 3   6 ADD(2)      2 -4, 1, 2, 3   7 ADD(8)      2 -4, 1, 2, 3, 8   8 ADD(-1000)  2 -1000, -4, 1, 2, 3, 8   9 GET         3 -1000, -4, 1, 2, 3, 8                1 10 GET        4 -1000, -4, 1, 2, 3, 8                2 11 ADD(2)     4 -1000, -4, 1, 2, 2, 3, 8   

It is required to work out an efficient algorithm which treats a given sequence of transactions. The maximum number of ADD and GET transactions: 30000 of each type.


Let us describe the sequence of transactions by two integer arrays:


1. A(1), A(2), ..., A(M): a sequence of elements which are being included into Black Box. A values are integers not exceeding 2 000 000 000 by their absolute value, M <= 30000. For the Example we have A=(3, 1, -4, 2, 8, -1000, 2).

2. u(1), u(2), ..., u(N): a sequence setting a number of elements which are being included into Black Box at the moment of first, second, ... and N-transaction GET. For the Example we have u=(1, 2, 6, 6).

The Black Box algorithm supposes that natural number sequence u(1), u(2), ..., u(N) is sorted in non-descending order, N <= M and for each p (1 <= p <= N) an inequality p <= u(p) <= M is valid. It follows from the fact that for the p-element of our u sequence we perform a GET transaction giving p-minimum number from our A(1), A(2), ..., A(u(p)) sequence.


Input
Input contains (in given order): M, N, A(1), A(2), ..., A(M), u(1), u(2), ..., u(N). All numbers are divided by spaces and (or) carriage return characters.
Output
Write to the output Black Box answers sequence for a given sequence of transactions, one number each line.
Sample Input
7 43 1 -4 2 8 -1000 21 2 6 6
Sample Output
3312
题目大意:不断往一个数列中加数,数列始终保持不减。在一些特定的时刻查找第 i 大的数。

一开始用 set 模拟,WA了,因为相同的数不能插入两次。后改用优先队列A了,方法大致如下:设上一时刻输出的值为 t ,则用一个最小值优先的队列存大于 t 的值,用一个最大值优先的队列存小于等于 t 的值,通过调整两个队列中的元素找出要求值。

#include<cstdio>#include<queue>#include<algorithm>using namespace std;const int maxn = 30000 + 5;int a[maxn],u[maxn];int n,m;priority_queue<int,vector<int>,greater<int> > s1;priority_queue<int,vector<int>,less<int> >s2;int main(){    int t,q,l,r,p;    q = 1,p = 0;    scanf("%d %d",&m,&n);    for(int i = 1;i <= m; ++i) scanf("%d",&a[i]);    for(int i = 1;i <= n; ++i) scanf("%d",&u[i]);    for(int i = 1;i <= m; ++i)    {        if(a[i] > p) s1.push(a[i]);        else s2.push(a[i]);        while(i == u[q] && q <= n)        {            l = s2.size(),r = s1.size();            if(q < l)            {                for(int j = l;j > q; --j)                {                    t = s2.top(),s2.pop();                    s1.push(t);                }            }            else if(q > l)            {                for(int j = l;j < q; ++j)                {                    t = s1.top(),s1.pop();                    s2.push(t);                }            }            p = s2.top();            printf("%d\n",p);            ++q;        }    }    return 0;}

D - Leading Trailing

You are given two integers: n andk, your task is to find the most significant three digits, and least significant three digits ofnk.


Input

Input starts with an integer T (≤ 1000), denoting the number of test cases.

Each case starts with a line containing two integers:n (2 ≤ n < 231) andk (1 ≤ k ≤ 107).

Output

For each case, print the case number and the three leading digits (most significant) and three trailing digits (least significant). You can assume that the input is given such thatnk contains at least six digits.

Sample Input

5

123456 1

123456 2

2 31

2 32

29 8751919

Sample Output

Case 1: 123 456

Case 2: 152 936

Case 3: 214 648

Case 4: 429 296

Case 5: 665 669

题目大意:给定 n ^ k ,求前三位和后三位。

后三位快速幂取模即可,这里简单说一下前三位取法,可以使用对数,log10 ( n ^ k ) = k log10 ( n ) ,设结果的整数部分为 a ,小数部分为 b 。则 10 ^ b 确定 n ^ k 的尾数。b =(double)k log10 ( n ) - (int)k log10 ( n ) 。结果取   10^ b 的前三位即可。

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int fastpow(int a,int b,int c)
{
    int s = 1;
    a %= c;
    while(b > 0)
    {
        if(b&1) s = s * a % c;
        a = a * a % c;
        b >>= 1;
    }
    return s;
}
int main()
{
    int n,k,t,p,pp,T;
    int a[6];
    scanf("%d",&T);
    pp = T;
    while(T--)
    {
        scanf("%d %d",&n,&k);
        double x = (double)k * log10(n) - (int)(k * log10(n));
        a[0] = (int)(pow(10,x) * 100);
        int t = fastpow(n,k,1000),p = 100;
        for(int i = 1;i < 4; ++i)
        {
            a[i] = t / p;
            t %= p;
            p /= 10;
        }
        printf("Case %d: ",pp - T);
        for(int i = 0;i < 4; ++i)
        {
            if(i == 1) printf(" ");
            printf("%d",a[i]);
        }
        printf("\n");
    }
    return 0;

}

E - Aladdin and the Flying Carpet

It's said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a powerful Genie. Here we are concerned about the first mystery.

Aladdin was about to enter to a magical cave, led by the evil sorcerer who disguised himself as Aladdin's uncle, found a strange magical flying carpet at the entrance. There were some strange creatures guarding the entrance of the cave. Aladdin could run, but he knew that there was a high chance of getting caught. So, he decided to use the magical flying carpet. The carpet was rectangular shaped, but not square shaped. Aladdin took the carpet and with the help of it he passed the entrance.

Now you are given the area of the carpet and the length of the minimum possible side of the carpet, your task is to find how many types of carpets are possible. For example, the area of the carpet 12, and the minimum possible side of the carpet is 2, then there can be two types of carpets and their sides are: {2, 6} and {3, 4}.


Input

Input starts with an integer T (≤ 4000), denoting the number of test cases.

Each case starts with a line containing two integers:a b (1 ≤ b ≤ a ≤ 1012) wherea denotes the area of the carpet andb denotes the minimum possible side of the carpet.

Output

For each case, print the case number and the number of possible carpets.

Sample Input

2

10 2

12 2

Sample Output

Case 1: 1

Case 2: 2

题目大意:给定一个矩形(不是正方形)的面积,问它的边有多少种不同的组成方式,最小边的长度不小于b。

唯一分解定理的运用。求出 a 的所有因子个数,除二便是边的对数。暴力出小于 b 的所有对数,跟前面的减一下就得到了。数据最大是 1e12,素数表打到 1e6 即可,因为大于 1e6 的因子最多有1个,所以除掉所有小于 1e6 的因子后判断一下剩下的部分是否大于 1 即可知道是否有大于 1e7 的因子。

虽然过了但是差点超了时限,dalao说是常数太大,后续再改进吧。。。

#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 5;
bool p[maxn];
int c[maxn];
void Getprime()
{
    memset(p,false,sizeof(p));
    int m = sqrt(maxn + 0.5);
    for(int i = 2;i <= m; ++i)
    {
        if(!p[i])
            for(int j = i * i;j <= maxn; j += i) p[j] = true;
    }
}
int main()
{
    Getprime();
    int j = 0,sum;
    for(int i = 2;i <= maxn; ++i) if(!p[i]) c[j++] = i;
    int t,pp;
    long long a,b;
    scanf("%d",&t);
    pp = t;
    while(t--)
    {
        sum = 1;
        scanf("%lld %lld",&a,&b);
        long long te = a;
        if(b * b > a) sum = 0;
        else
        {
            for(int i = 0;i < j && te > 1; ++i)
            {
                if(te % c[i] == 0)
                {
                    int mark = 1;
                    while(te % c[i] == 0 && te > 1)
                    {
                        te /= c[i];
                        ++mark;
                    }
                    sum = sum * mark;
                }
            }
            if(te > 1) sum <<= 1;
            sum >>= 1;
            for(int i = 1;i < b; ++i) if(a % i == 0) --sum;
        }
        printf("Case %d: %d\n",pp - t,sum);
    }
    return 0;
}

L - Bi-shoe and Phi-shoe

Bamboo Pole-vault is a massively popular sport in Xzhiland. And Master Phi-shoe is a very popular coach for his success. He needs some bamboos for his students, so he asked his assistant Bi-Shoe to go to the market and buy them. Plenty of Bamboos of all possible integer lengths (yes!) are available in the market. According to Xzhila tradition,

Score of a bamboo = Φ (bamboo's length)

(Xzhilans are really fond of number theory). For your information,Φ (n) = numbers less thann which are relatively prime (having no common divisor other than 1) ton. So, score of a bamboo of length 9 is 6 as 1, 2, 4, 5, 7, 8 are relatively prime to 9.

The assistant Bi-shoe has to buy one bamboo for each student. As a twist, each pole-vault student of Phi-shoe has a lucky number. Bi-shoe wants to buy bamboos such that each of them gets a bamboo with a score greater than or equal to his/her lucky number. Bi-shoe wants to minimize the total amount of money spent for buying the bamboos. One unit of bamboo costs 1 Xukha. Help him.


Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a line containing an integern (1 ≤ n ≤ 10000) denoting the number of students of Phi-shoe. The next line containsn space separated integers denoting the lucky numbers for the students. Each lucky number will lie in the range[1, 106].

Output

For each case, print the case number and the minimum possible money spent for buying the bamboos. See the samples for details.

Sample Input

3

5

1 2 3 4 5

6

10 11 12 13 14 15

2

1 1

Sample Output

Case 1: 22 Xukha

Case 2: 88 Xukha

Case 3: 4 Xukha

题目大意:一个数的价值(value)被定义为小于它的并与它互质的数的个数,给定一系列数(lucky number),对于每个 lucky number 找到一个 value 大于它的最小的数,求这些数的和。

大致推一下就能发现每根竹子的长度取素数性价比最高,于是打了个素数表水过了。后来看了下题解用的是欧拉筛,新技能 get 了。
#include<cstdio>
#include<algorithm>
#include<set>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 1e6 * 2;
bool p[maxn];
void Getprime()
{
    memset(p,false,sizeof(p));
    int m = sqrt(maxn + 0.5);
    for(int i = 2;i <= m; ++i)
    {
        if(!p[i]) for(int j = i * i;j <= maxn; j += i) p[j] = true;
    }
}
set<int> s;
int main()
{
    Getprime();
    int t,n,pp,x;
    long long sum;
    for(int i = 2;i <= maxn; ++i) if(!p[i]) s.insert(i - 1);
    scanf("%d",&t);
    pp = t;
    while(t--)
    {
        sum = 0;
        scanf("%d",&n);
        for(int i = 0;i < n; ++i)
        {
            scanf("%d",&x);
            set<int>::iterator it;
            it = s.lower_bound(x);
            sum += (*(it) + 1);
        }
        printf("Case %d: %lld Xukha\n",pp - t,sum);
    }
    return 0;
}