Nenu 复建训练#1

日更博客+补题了(发现自己极其菜)


A - Fashion in Berland #Codeforces 691A

According to rules of the Berland fashion, a jacket should be fastened by all the buttons except only one, but not necessarily it should be the last one. Also if the jacket has only one button, it should be fastened, so the jacket will not swinging open.

You are given a jacket with n buttons. Determine if it is fastened in a right way.

INPUT

The first line contains integer n (1 ≤ n ≤ 1000) — the number of buttons on the jacket.

The second line contains n integers ai (0 ≤ ai ≤ 1). The number ai = 0 if the i-th button is not fastened. Otherwise ai=1.

OUTPUT

In the only line print the word "YES" if the jacket is fastened in a right way. Otherwise print the word "NO".

Examples

3
1 0 1
YES
-------
3
1 0 0
NO

题意:简单的循环题,有题意可得非常简单的判断公式(需要在 n=1 的时候做一下特判)

                                                                                   \sum_{i=1}^{n}{a_i}=n-1

Code:

#include
#include
#include
using namespace std;
int n,x,sum;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&x);
		if(x==1) sum++;
	}
	if(n==1&&sum==1||n>1&&sum==n-1) printf("YES");
	else printf("NO");
	return 0;
} 

B - Exponential notation #Codeforces 691C

You are given a positive decimal number x.

Your task is to convert it to the "simple exponential notation".

Let x=a*10^{b}, where1\leq a <10 then in general case the "simple exponential notation" looks like "aEb". If b equals to zero, the part "Eb" should be skipped. If a is an integer, it should be written without decimal point. Also there should not be extra zeroes in a and b.

INPUT

The only line contains the positive decimal number x. The length of the line will not exceed 106. Note that you are given too large number, so you can't use standard built-in data types "float", "double" and other.

OUTPUT

Print the only line — the "simple exponential notation" of the given number x.

Examples

16
1.6E1
-------
01.23400
1.234
-------
.100
1E-1
-------
100.
1E2

题意:模拟题,对科学计数法的另类解释,注意模拟判断点的略去

Code:

#include
#include
#include
#include
#include
#include
#define res register int
using namespace std;
const int maxn=1e6+12;
char s[maxn],ans[maxn];
int inss,st,tail,num;
int main(){
    scanf("%s",s);
    int len=strlen(s);
    int cnt=0;inss=len;
    for(res i=0;i=0;i--){
	if(s[i]!='0'&&s[i]!='.'){
	    tail=i;break;
	}
    }
    for(res i=0;ist) num=inss-st-1;
    else num=inss-st;
    printf("%c",s[st]);
    if(tail>st) printf(".");
    for(res i=st+1;i<=tail;i++){
	if(s[i]!='.') printf("%c",s[i]);
    }
    if(num!=0) printf("E%d",num);  
    return 0;
}

C - Swaps in Permutation #Codeforces 691D

You are given a permutation of the numbers 1, 2, ..., n and m pairs of positions{{a_j,b_j}}.

At each step you can choose a pair from the given positions and swap the numbers in that positions. What is the lexicographically maximal permutation one can get?

Let p and q be two permutations of the numbers 1, 2, ..., n. p is lexicographically smaller than the q if a number 1\leq i \leq n exists, so p_k=q_k for 1\leq k<i andp_i<q_i.

INPUT

The first line contains two integers n and m (1 ≤ n, m ≤ 106) — the length of the permutation p and the number of pairs of positions.

The second line contains n distinct integers p i (1 ≤ p i ≤ n) — the elements of the permutation p.

Each of the last m lines contains two integers (a j, b j) (1 ≤ a j, b j ≤ n) — the pairs of positions to swap. Note that you are given a positions, not the values to swap.

OUTPUT

Print the only line with n distinct integers p'_i (1 \leq p'_i \leq n) — the lexicographically maximal permutation one can get.

Examples

Input
9 6
1 2 3 4 5 6 7 8 9
1 4
4 7
2 5
5 8
3 6
6 9

Output
7 8 9 4 5 6 1 2 3

题意:给出可以交换的数对,以字典序打印排序后的数列

我们考虑每两个数可以被交换,那么每个数的祖先一定是多个可交换数对最前面的数,于是我们在数列的每一位维护一个队列,先建立并查集,然后从头开始遍历,将每一个数通过并查集压进其祖先数位队列之中,最后打印时直接按位遍历释放就可以了

Code:

#include
#include
#include
#include
#define res register int
using namespace std;
const int maxn=1e6+12;
priority_queue num[maxn];
int n,m,a,b,s[maxn],fa[maxn];
inline int findfa(int x){
	return (fa[x]==x)?x:fa[x]=findfa(fa[x]);
}
inline void merge(int x,int y){
    int xx=findfa(x);
    int yy=findfa(y);
    if (xx!=yy) fa[xx]=yy;
}
inline void init(int x){
	for(res i=1;i<=x;i++) fa[i]=i;
}
int main(){
    scanf("%d%d",&n,&m);
    for(res i=1;i<=n;i++) scanf("%d",&s[i]);
    init(n);
    for(res i=1;i<=m;i++){
    	scanf("%d%d",&a,&b);
    	merge(a,b); 
	}
    for(res i=1;i<=n;i++) num[fa[findfa(i)]].push(s[i]);
    for(res i=1;i<=n;i++){
        printf("%d ",num[fa[i]].top());
        num[fa[i]].pop();
    }
    return 0;
}

D - Xor-sequences #Codeforces691E

You are given n integers a_1,a_2,...,a_n

A sequence of integers x_1,x_2,...,x_k is called a “xor-sequence” if for every 1  ≤  i  ≤  k - 1 the number of ones in the binary representation of the numberx_i  xorx_{i+1} ’s is a multiple of 3 and for all 1 ≤ i ≤ k. The symbol is used for the binary exclusive or operation.

How many “Xor-sequences” of length k exist? Output the answer modulo 10^{9}+7.

Note if a = [1, 1] and k = 1 then the answer is 2, because you should consider the ones from a as different.

INPUT

The first line contains two integers n and k( 1 \leq n \leq 100,1 \leq k \leq 10^{18})— the number of given integers and the length of the "xor-sequences".

The second line contains n integers a_i(0 \leq a_i \leq 10^{18}).

OUTPUT

Print the only integer c — the number of "xor-sequences" of length k modulo 10^{9}+7.

Examples

Input
5 2
15 1 2 4 8
Output
13
----------
Input
5 1
15 1 2 4 8
Output
5

 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二进制中1的个数是3的倍数。问长度为k的满足条件的序列有多少种?

dp状态定义为在前i个数中以aj为结尾的方案数量,则转移为

                                                                 \sum_{j=1}^{i}{dp[i][[j]\ a[i]\ \ xor \ \ a[j]mod3\ \equiv 1}

因为是求和的转移,可以用矩阵快速幂将O(n)的求和加速为log级别

Code:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define res register int
#define dd double
#define ull unsigned long long
#define pb push_back
#define pii pair
#define fi first
#define se second
#define Mp make_pair
using namespace std;
const int maxn=3e5+12;
inline int ri(){
    int a=0,b=1;
    char px=getchar();
    while(!isdigit(px)){if(px=='-')b=-1;px=getchar();}
    while(isdigit(px)) {a=a*10+px-'0';	px=getchar();}
    return a*b;
}
inline ll rl(){
    ll a=0,b=1;
    char px=getchar();
    while(!isdigit(px)){if(px=='-')b=-1;px=getchar();}
    while(isdigit(px)) {a=a*10+px-'0';	px=getchar();}
    return a*b;
}
ll a[maxn];
ll dp[105][105];
struct matrix {//矩阵
    int n;//长
    int m;//宽
    long long a[105][105];
    matrix() {//构造函数
        n = 2;
        m = 2;
        memset(a, 0, sizeof(a));
    }
    matrix(int x, int y) {
        n = x;
        m = y;
        memset(a, 0, sizeof(a));
    }
    void print() {
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                printf("%d ", a[i][j]);
            }
            printf("\n");
        }
    }
    void setv(int x) {//初始化
        if(x == 0) {
            memset(a, 0, sizeof(a));
        }
        if(x == 1) {
            memset(a, 0, sizeof(a));
            for(int i = 1; i <= n; i++) a[i][i] = 1;
        }
    }
    friend matrix operator *(matrix x, matrix y) { //矩阵乘法
        matrix tmp = matrix(x.n, y.m);
        for(int i = 1; i <= x.n; i++) {
            for(int j = 1; j <= y.m; j++) {
                tmp.a[i][j] = 0;
                for(int k = 1; k <= y.n; k++) {
                    tmp.a[i][j] += (x.a[i][k] * y.a[k][j]) % mod;
                }
                tmp.a[i][j] %= mod;
            }
        }
        return tmp;
    }
};
int n;
ll  k;
matrix fast_pow(matrix x, long long k) { //矩阵快速幂
    matrix ans = matrix(n, n);
    ans.setv(1);//初始化为1
    while(k > 0) { //类似整数快速幂
        if(k & 1) {
            ans = ans * x;
        }
        k >>= 1;
        x = x * x;
    }
    return ans;
}

int cal(ll x) {
    int cnt = 0;
    while(x) {
        if(x & 1 ) {
            cnt++;
        }
        x /= 2;
    }
    return cnt;
}
int main() {
    scanf("%d%lld", &n, &k);
    for(int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
    }
    matrix xor_mat = matrix(n, n);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            if(cal(a[i]^a[j]) % 3 == 0 )    xor_mat.a[i][j] = 1;
            else xor_mat.a[i][j] = 0;
        }
    }
    xor_mat = fast_pow(xor_mat, k - 1);
    LL ans = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            ans += xor_mat.a[i][j];
        }
        ans %= mod;
    }
    cout << ans << endl;
    return 0;
}

 E - Couple Cover #Codefroces691F

Couple Cover, a wildly popular luck-based game, is about to begin! Two players must work together to construct a rectangle. A bag with n balls, each with an integer written on it, is placed on the table. The first player reaches in and grabs a ball randomly (all balls have equal probability of being chosen) — the number written on this ball is the rectangle's width in meters. This ball is not returned to the bag, and the second player reaches into the bag and grabs another ball — the number written on this ball is the rectangle's height in meters. If the area of the rectangle is greater than or equal some threshold p square meters, the players win. Otherwise, they lose.

The organizers of the game are trying to select an appropriate value for p so that the probability of a couple winning is not too high and not too low, but they are slow at counting, so they have hired you to answer some questions for them. You are given a list of the numbers written on the balls, the organizers would like to know how many winning pairs of balls exist for different values of p. Note that two pairs are different if either the first or the second ball is different between the two in pair, and two different balls with the same number are considered different.

INPUT

The input begins with a single positive integer n in its own line (1 ≤ n ≤ 10^{6}).

The second line contains n positive integers — the i-th number in this line is equal to ai (1 ≤ ai ≤ 3·10^{6}), the number written on the i-th ball.

The next line contains an integer m (1 ≤ m ≤ 106), the number of questions you are being asked.

Then, the following line contains m positive integers — the j-th number in this line is equal to the value of p (1 ≤ p ≤ 3·106) in the j-th question you are being asked.

OUTPUT

For each question, print the number of winning pairs of balls that exist for the given value of p in the separate line.

Examples

Input
5
4 2 6 1 3
4
1 3 5 8
Output
20
18
14
10
-----------
Input
2
5 6
2
30 31
Output
2
0

 思路:可以先预处理出乘积小于某个数的方案数。先用一个数组统计每个数字出现的次数,再枚举最大数以内的每个数,算出每个乘积,用乘法原理和加法原理做出可以得到该乘积的方案数,最后求出前缀为小于等于这个数的方案数。询问时只需总数减去小于这个数的方案数即可。

Code:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define res register int
#define dd double
#define ull unsigned long long
#define pb push_back
#define pii pair
#define fi first
#define se second
#define Mp make_pair
using namespace std;
const int maxn=1e6+12;
int n,a[maxn],tot[maxn*3];
long long f[maxn*3];
int main(){
    scanf("%d",&n);
    memset(tot,0,sizeof(tot));
    int mx=0;
    for(res i=1;i<=n;i++) scanf("%d",&a[i]),tot[a[i]]++,mx=max(mx,a[i]);
    for(res i=0;i<=mx;i++){
        for(res j=0;j<=mx;j++){
            if (1ll*i*j>3000000) break;
            if (i!=j) f[i*j]+=1ll*tot[i]*tot[j];
            else f[i*j]+=max(1ll*tot[i]*(tot[i]-1),0ll);
        }
    }
    for (i=1;i<=maxn*3;i++) f[i]+=f[i-1];
    int q;
    scanf("%d",&q);
    while (q--){
        int x;
        scanf("%d",&x);
        printf("%lld\n",1ll*n*(n-1)-f[x-1]);
    }
    return 0;
}

 

你可能感兴趣的:(Nenu复建训练)