第三次codeforces竞技结束 #254 Div 2

掉到绿名喽……谁教我这次作死一定要做D也就是Div1的B题……唉叹口气……

A. DZY Loves Chessboard

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves chessboard, and he enjoys playing with it.

He has a chessboard of n rows and m columns. Some cells of the chessboard are bad, others are good. For every good cell, DZY wants to put a chessman on it. Each chessman is either white or black. After putting all chessmen, DZY wants that no two chessmen with the same color are on two adjacent cells. Two cells are adjacent if and only if they share a common edge.

You task is to find any suitable placement of chessmen on the given chessboard.

Input

The first line contains two space-separated integers n and m (1 ≤ n, m ≤ 100).

Each of the next n lines contains a string of m characters: the j-th character of the i-th string is either "." or "-". A "." means that the corresponding cell (in the i-th row and the j-th column) is good, while a "-" means it is bad.

Output

Output must contain n lines, each line must contain a string of m characters. The j-th character of the i-th string should be either "W", "B" or "-". Character "W" means the chessman on the cell is white, "B" means it is black, "-" means the cell is a bad cell.

If multiple answers exist, print any of them. It is guaranteed that at least one answer exists.

Sample test(s)
input
1 1
.
output
B
input
2 2
..
..
output
BW
WB
input
3 3
.-.
---
--.
output
B-B
---
--B
Note

In the first sample, DZY puts a single black chessman. Of course putting a white one is also OK.

In the second sample, all 4 cells are good. No two same chessmen share an edge in the sample output.

In the third sample, no good cells are adjacent. So you can just put 3 chessmen, no matter what their colors are.



这是一个水题,要求减号输出减号,点号输出黑白BW,相邻格子不让颜色一致,那么事先做一张国际象棋那样的格子表,遇到点输出,遇到减号输出减号即可。

5Min秒掉,但是……又忘记把Freopen删掉结果TLE At 1 了一次……

Code:

#include <cmath>   
#include <vector>  
#include <cctype>  
#include <cstdio>  
#include <string>  
#include <cstdlib>  
#include <cstring>  
#include <iostream>  
#include <algorithm>  
using namespace std;
char map[101][101];

int main()
{
	//freopen("in.txt","r",stdin);
	int n,m;
	scanf("%d%d",&n,&m);
	char huiche;
	scanf("%c",&huiche);
	//printf("%d %d\n",n,m); 中途改题 ?!! 
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			char ch;
			scanf("%c",&ch);
			if(ch=='-')printf("-");
			else if(ch=='.')printf((i+j)%2==0?"B":"W");
			else printf("%c",ch);
		}
		if(i==n-1)return 0;
		else 
		{
			scanf("%c",&huiche);
			printf("\n");
		}
	}
	
	return 0;
}

B. DZY Loves Chemistry

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves chemistry, and he enjoys mixing chemicals.

DZY has n chemicals, and m pairs of them will react. He wants to pour these chemicals into a test tube, and he needs to pour them in one by one, in any order.

Let's consider the danger of a test tube. Danger of an empty test tube is 1. And every time when DZY pours a chemical, if there are already one or more chemicals in the test tube that can react with it, the danger of the test tube will be multiplied by 2. Otherwise the danger remains as it is.

Find the maximum possible danger after pouring all the chemicals one by one in optimal order.

Input

The first line contains two space-separated integers n and m .

Each of the next m lines contains two space-separated integers xi and yi (1 ≤ xi < yi ≤ n). These integers mean that the chemical xi will react with the chemical yi. Each pair of chemicals will appear at most once in the input.

Consider all the chemicals numbered from 1 to n in some order.

Output

Print a single integer — the maximum possible danger.

Sample test(s)
input
1 0
output
1
input
          
          
2 1
1 2
output
2
input
          
          
3 2
1 2
2 3
output
4
Note

In the first sample, there's only one way to pour, and the danger won't increase.

In the second sample, no matter we pour the 1st chemical first, or pour the 2nd chemical first, the answer is always 2.

In the third sample, there are four ways to achieve the maximum possible danger: 2-1-3, 2-3-1, 1-2-3 and 3-2-1 (that is the numbers of the chemicals in order of pouring).

并查集看有多少个集m,然后2的n-m次方即可……当时突然发现啊咧这是求连通分量个数的题么,并查集是啥来着…然后攻D去了…D的分多……
借用 Free_Way@CSDN 的代码以记忆模版:(他的算法是并查集记录Rank来做指数的方法,好厉害~~~)
自学并查集各种用法决定!

Code:

#include <cstdio>
int a[1000], rank[1000];
int find(int x)
{
    if(x != a[x])
    {
        a[x] = find(a[x]);
    }
    return a[x];
}
void union_set(int x, int y)
{
    x = find(x);
    y = find(y);
    if(x != y)
    {
        a[x] = y;
        rank[y] += rank[x];
        rank[x] = 1;
    }
}
long long pow(int x)
{
    long long temp = 1;
    for(int i = 0; i < x; i++)
    {
        temp *= 2;
    }
    return temp;
}
int main()
{
    int n, m, i;
    long long ans;
    while(~scanf("%d %d", &n, &m))
    {
        for(int i = 1; i <= n; i++)
        {
            a[i] = i;
            rank[i] = 1;
        }
        for(int i = 0; i < m; i++)
        {
            int x, y;
            scanf("%d %d", &x, &y);
            union_set(x, y);
        }
        ans = 1;
        for(int i = 1; i <= n; i++)
        {
            if(rank[i] != 1)
            {
                ans *= pow(rank[i]-1);
            }
        }
        printf("%I64d\n", ans);
    }
    return 0;
}



D. DZY Loves FFT

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves Fast Fourier Transformation, and he enjoys using it.

Fast Fourier Transformation is an algorithm used to calculate convolution. Specifically, if ab and c are sequences with length n, which are indexed from 0 to n - 1, and

We can calculate c fast using Fast Fourier Transformation.

DZY made a little change on this formula. Now

To make things easier, a is a permutation of integers from 1 to n, and b is a sequence only containing 0 and 1. Given a and b, DZY needs your help to calculate c.

Because he is naughty, DZY provides a special way to get a and b. What you need is only three integers ndx. After getting them, use the code below to generate a and b.

//x is 64-bit variable;
function getNextX() {
    x = (x * 37 + 10007) % 1000000007;
    return x;
}
function initAB() {
    for(i = 0; i < n; i = i + 1){
        a[i] = i + 1;
    }
    for(i = 0; i < n; i = i + 1){
        swap(a[i], a[getNextX() % (i + 1)]);
    }
    for(i = 0; i < n; i = i + 1){
        if (i < d)
            b[i] = 1;
        else
            b[i] = 0;
    }
    for(i = 0; i < n; i = i + 1){
        swap(b[i], b[getNextX() % (i + 1)]);
    }
}

Operation x % y denotes remainder after division x by y. Function swap(x, y) swaps two values x and y.

Input

The only line of input contains three space-separated integers n, d, x (1 ≤ d ≤ n ≤ 100000; 0 ≤ x ≤ 1000000006). Because DZY is naughty, x can't be equal to 27777500.

Output

Output n lines, the i-th line should contain an integer ci - 1.

Sample test(s)
input
3 1 1
output
1
3
2
input
5 4 2
output
2
2
4
5
5
input
5 4 3
output
5
5
5
5
4
Note

In the first sample, a is [1 3 2]b is [1 0 0], so c0 = max(1·1) = 1c1 = max(1·0, 3·1) = 3c2 = max(1·0, 3·0, 2·1) = 2.

In the second sample, a is [2 1 4 5 3]b is [1 1 1 0 1].

In the third sample, a is [5 2 1 4 3]b is [1 1 1 1 0].


然后攻的是D题,以下为题目以及小数据代码(可惜cf没有小数据给半分这种,叹气):(TLE At 9)

这题一个是要把他给的式子模拟出来以获得初始A和B的数组初值,然后找题求最大,下面模拟了一下,所以为什么说我是作死呢……

Code1:

#include <cmath>   
#include <vector>  
#include <cctype>  
#include <cstdio>  
#include <string>  
#include <cstdlib>  
#include <cstring>  
#include <iostream>  
#include <algorithm>
#define MAXN 100001  
using namespace std;

typedef __int64 ll;
ll n,d,x,a[MAXN],b[MAXN],lst[MAXN];

ll getNextX() 
{
    x = (x * 37 + 10007) % 1000000007;
    return x;
}

void initAB() 
{
	ll i;
    for(i = 0; i < n; i++)        a[i] = i + 1;
    for(i = 0; i < n; i++)        
	{
		ll t = getNextX() % (i + 1);
		ll temp = a[i];
		a[i] = a[t];
		a[t] = temp;
	}//swap(a[i], a[getNextX() % (i + 1)]);
    for(i = 0; i < n; i++)
        if (i < d)      b[i] = 1;
        else            b[i] = 0;
    for(i = 0; i < n; i++)        
	{
		ll t = getNextX() % (i + 1);
		ll temp = b[i];
		b[i] = b[t];
		b[t] = temp;
	}//swap(b[i], b[getNextX() % (i + 1)]);
}

ll solve(ll k)
{
	memset(lst,0,sizeof lst);
	ll j,ans=0;
	ll p = 0;
	for(j = 0;j <= k;j++)
	{
		if (b[j] == 0)continue;//jianzhi
		else 
		{
			lst[p] = a[k-j];
			//cout<<p<<"\t"<<a[k-j]<<endl;
			p++;
		}
	}
	//sort(lst,lst+p);
	for(int ii=0;ii<=p;ii++)
	if(lst[ii]>ans)ans=lst[ii];
	return ans;
}

int main()
{
	ll k;
	memset(a,0,sizeof a);
	memset(b,0,sizeof b);
	memset(lst,0,sizeof lst);
	scanf("%I64d%I64d%I64d",&n,&d,&x);
	initAB();
	//for(k=0;k<n;k++)	printf("%I64d\t%I64d\n",a[k],b[k]);
	for(k=0;k<n;k++)
	{
		printf("%I64d",solve(k));
		if(k<n-1)printf("\n");
	}
	return 0;
}


Code2:

之前剪枝剪的太少,跟没有一样,后来弄了多组答案之后发现,很多答案都是一片一片一样的,然后去找原因……然后……好吧……

从后向前批量刷c(就是答案数组)的值,算法时间在CF上百毫秒以内……

From andrei14vl@Codeforces

#include <iostream>
#include <algorithm>
using namespace std;

int i, n, d, a[100009], b[100009], c[100009], aPoz[100009];
long long x;

long long getNextX() 
{
    x = (x * 37 + 10007) % 1000000007;
    return x;
}

void initAB() 
{
    for(i = 0; i < n; i = i + 1)
        a[i] = i + 1;
    for(i = 0; i < n; i = i + 1)
        swap(a[i], a[getNextX() % (i + 1)]);
    for(i = 0; i < n; i = i + 1)
        if (i < d)      b[i] = 1;
        else            b[i] = 0;
    for(i = 0; i < n; i = i + 1)
        swap(b[i], b[getNextX() % (i + 1)]);
}

int main()
{
    cin >> n >> d >> x;
    initAB();
    
    for (int i = 0; i < n; ++i)
        aPoz[a[i]] = i + 1;
    int bcnt = -1;
    for (int i = 0; i < n; ++i)
        if (b[i])
            b[++bcnt] = i;
        
    int n2 = n; 
    for (int i = 100000; i > 0; --i)
        if (aPoz[i])
        {
            for (int j = 0; j <= bcnt; ++j)
            {
                if (aPoz[i] + b[j] > n2) break;
                if (!c[aPoz[i] + b[j]])
                    c[aPoz[i] + b[j]] = i;
            }
            while (c[n2]) --n2;
        }
    for (int i = 1; i <= n; ++i)
        cout << c[i] << endl;   
        
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糖果天王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值