Codeforces 483 - A/B/C/D/E - (Done)
题目链接:http://codeforces.com/contest/483
A - Counterexample - [简单构造题]
Your friend has recently learned about coprime numbers. A pair of numbers $(a, b)$ is called coprime if the maximum number that divides both $a$ and $b$ is equal to one.
Your friend often comes up with different statements. He has recently supposed that if the pair $(a, b)$ is coprime and the pair $(b, c)$ is coprime, then the pair $(a, c)$ is coprime.
You want to find a counterexample for your friend's statement. Therefore, your task is to find three distinct numbers $(a, b, c)$, for which the statement is false, and the numbers meet the condition $l \le a < b < c \le r$.
More specifically, you need to find three numbers $(a, b, c)$, such that $l \le a < b < c le r$, pairs $(a, b)$ and $(b, c)$ are coprime, and pair $(a, c)$ is not coprime.
Input
The single line contains two positive space-separated integers $l, r (1 \le l \le r \le 10^18; r - l \le 50)$.
Output
Print three positive space-separated integers $a, b, c$ — three distinct numbers $(a, b, c)$ that form the counterexample. If there are several solutions, you are allowed to print any of them. The numbers must be printed in ascending order.
If the counterexample does not exist, print the single number $-1$.
Examples
Input
2 4
Output
2 3 4
Input
10 11
Output
-1
Input
900000000000000009 900000000000000029
Output
900000000000000009 900000000000000010 900000000000000021
Note
In the first sample pair (2, 4) is not coprime and pairs (2, 3) and (3, 4) are.
In the second sample you cannot form a group of three distinct integers, so the answer is -1.
In the third sample it is easy to see that numbers 900000000000000009 and 900000000000000021 are divisible by three.
题意:
在给定的 $[l,r]$ 里找到三个数字 $a,b,c$,满足 $gcd(a,b) = 1, gcd(b,c) = 1, gcd(a,c) > 1$。
题解:
相邻两个整数必然互质,相邻两个奇数必然互质。因此只能找连续的三个为偶奇偶的数。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll l,r;
int main()
{
cin>>l>>r;
ll a=(l%==)?l:l+;
ll b=a+, c=b+;
if(c<=r) printf("%lld %lld %lld\n",a,b,c);
else printf("-1\n");
}
B - Friends and Presents - [二分]
You have two friends. You want to present each of them several positive integers. You want to present $cnt_1$ numbers to the first friend and $cnt_2$ numbers to the second friend. Moreover, you want all presented numbers to be distinct, that also means that no number should be presented to both friends.
In addition, the first friend does not like the numbers that are divisible without remainder by prime number $x$. The second one does not like the numbers that are divisible without remainder by prime number $y$. Of course, you're not going to present your friends numbers they don't like.
Your task is to find such minimum number $v$, that you can form presents using numbers from a set $1, 2, ..., v$. Of course you may choose not to present some numbers at all.
A positive integer number greater than $1$ is called prime if it has no positive divisors other than $1$ and itself.
Input
The only line contains four positive integers $cnt_1, cnt_2, x, y (1 \le cnt1, cnt2 < 10^9; cnt1 + cnt2 \le 10^9; 2 \le x < y \le 3·10^4)$ — the numbers that are described in the statement. It is guaranteed that numbers $x, y$ are prime.
Output
Print a single integer — the answer to the problem.
Examples
input
3 1 2 3
output
5
input
1 3 2 3
output
4
Note
In the first sample you give the set of numbers {1, 3, 5} to the first friend and the set of numbers {2} to the second friend. Note that if you give set {1, 3, 5} to the first friend, then we cannot give any of the numbers 1, 3, 5 to the second friend.
In the second sample you give the set of numbers {3} to the first friend, and the set of numbers {1, 2, 4} to the second friend. Thus, the answer to the problem is 4.
题意:
现在要给两个人赠送一些正整数,要给第一个人送 $cnt_1$ 个正整数,要给第二个人送 $cnt_2$ 个正整数,且第一个人不想要能被 $x$ 整除的数,第二个人不想要能被 $y$ 整除的数。
现在你要求出最小的正整数 $v$,意味着你送出的正整数全部属于 $1 \sim v$。
题解:
二分倒是不难想到,就是算怎么给两人整数不太好想。
举个栗子:假设我现在 $v=7,x=2,y=3,cnt_1=3,cnt_2=3$,显然此时能给第一个人的数字有 $1,3,5,7$,能给第二个人的数字有 $1,2,4,5,7$;
那么我们知道,为了尽量使得 $v$ 小,我们应该尽量把第二个人不要的数字塞给第一个人,比如第二个人是不要 $3$ 的,但第一个人要,所以可以塞给他;同理,第一个人不要 $2,4$,但是第二个人要,可以塞给他;
假设 $1 \sim v$ 中能被 $x$ 整除的数有 $cnt_x$ 个,能被 $y$ 整除的数有 $cnt_y$ 个,能被 $xy$ 整除的数有 $cnt_xy$ 个;因此,第二个人不要而第一个人要的数字,其数量为 $cnt_y - cnt_xy$,第一个人不要而第二个人要的数字,其数量为 $cnt_x - cnt_xy$;
那么剩下来再要送出去的数字,就既不能被 $x$ 整除,也不能被 $y$ 整除了,如果这些数够分,那么 $v$ 就是可行的,不够分的话 $v$ 就不可行。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int cnt1,cnt2,x,y; int judge(int v)
{
int cnt_x=v/x, cnt_y=v/y, cnt_xy=v/(x*y);
int rest1=max(cnt1-(cnt_y-cnt_xy),);
int rest2=max(cnt2-(cnt_x-cnt_xy),);
return rest1+rest2<=v-cnt_x-cnt_y+cnt_xy;
} int main()
{
ios::sync_with_stdio();
cin.tie(); cin>>cnt1>>cnt2>>x>>y;
int l=, r=*(cnt1+cnt2);
while(l<r)
{
int mid=l+(r-l)/;
if(judge(mid)) r=mid;
else l=mid+;
}
cout<<l<<'\n';
}
C - Diverse Permutation - [构造题]
Permutation $p$ is an ordered set of integers $p_1, p_2, \cdots, p_n$, consisting of $n$ distinct positive integers not larger than $n$. We'll denote as n the length of permutation $p_1, p_2, \cdots, p_n$.
Your task is to find such permutation $p$ of length $n$, that the group of numbers $|p_1 - p_2|, |p_2 - p_3|, \cdots, |p_{n-1} - p_n|$ has exactly $k$ distinct elements.
Input
The single line of the input contains two space-separated positive integers $n, k (1 \le k < n \le 10^5)$.
Output
Print $n$ integers forming the permutation. If there are multiple answers, print any of them.
Examples
Input
3 2
Output
1 3 2
Input
3 1
Output
1 2 3
Input
5 2
Output
1 3 2 4 5
题意:
让你给出一个 $1 \sim n$ 的某个排列 $p$,使得 $|p_1 - p_2|, |p_2 - p_3|, \cdots, |p_{n-1} - p_n|$ 中包含 $k(1 \le k \le n-1)$ 个不同的数字。
题解:
实际上,要 $1 \sim n$ 的排列 $p$ 最多可以让 $k=n-1$,换句话说,只需要 $1 \sim k+1$ 的排列就能满足条件。
然后,第一步,把 $1$ 放到 $k$ 和 $k+1$ 之间,即可产生 $k-1,k$ 这两个不同的数字,而后,把 $2$ 放到 $k-1$ 和 $k$ 之间可产生 $k-3,k-2$ 这两个不同的数字。依次类推即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+;
int n,k;
int num[maxn];
void fill(int v,int k)
{
if(k<=) return;
num[k]=v;
num[k-]=num[k+]-;
fill(v+,k-);
}
int main()
{
cin>>n>>k;
for(int i=k+;i<=n;i++) num[i]=i;
fill(,k);
for(int i=;i<=n;i++) printf("%d%c",num[i],i<n?' ':'\n');
}
D - Interesting Array - [线段树]
We'll call an array of $n$ non-negative integers $a[1], a[2], ..., a[n]$ interesting, if it meets $m$ constraints. The $i$-th of the $m$ constraints consists of three integers $l_i, r_i, q_i (1 \le l_i \le r_i \le n)$ meaning that value $a[l_i] \& a[l_{i+1}] \& \cdots \& a[r_i]$ should be equal to $q_i$.
Your task is to find any interesting array of $n$ elements or state that such array doesn't exist.
Expression $x$&$y$ means the bitwise AND of numbers $x$ and $y$. In programming languages C++, Java and Python this operation is represented as "&", in Pascal — as "and".
Input
The first line contains two integers $n, m (1 \le n \le 10^5, 1 \le m \le 10^5)$ — the number of elements in the array and the number of limits.
Each of the next m lines contains three integers $l_i, r_i, q_i (1 \le l_i \le r_i \le n, 0 \le qi < 2^{30})$ describing the $i$-th limit.
Output
If the interesting array exists, in the first line print "YES" (without the quotes) and in the second line print n integers $a[1], a[2], ..., a[n] (0 \le a[i] < 2^{30})$ decribing the interesting array. If there are multiple answers, print any of them.
If the interesting array doesn't exist, print "NO" (without the quotes) in the single line.
Examples
Input
3 1
1 3 3
Output
YES
3 3 3
Input
3 2
1 3 3
1 3 2
Output
NO
题意:
给出 $n,m$,若数组 $a[1 \sim n]$ 满足 $m$ 项条件中的任意一项,则称它为有趣的。
第 $i$ 项条件表述为 $l_i, r_i, q_i (1 \le l_i \le r_i \le n, 0 \le q_i < 2^{30})$,即要求 $a[l_i] \& a[l_{i+1}] \& \cdots \& a[r_i] = q_i$。
现在要你构造一个有趣的数组 $a[1 \sim n]$。
题解:
初始全部 $a[i]=0$;考虑每一组 $l_i, r_i, q_i$,既然要 $a[l_i] \& a[l_{i+1}] \& \cdots \& a[r_i] = q_i$,那么就应当对区间 $[l,r]$ 内所有的 $a[i]|=q[i]$。
最后 $m$ 组要求全部完成后,再重新跑一遍 $m$ 个 $l_i, r_i, q_i$ 进行验证即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+;
const int maxm=1e5+;
int n,m;
int l[maxm],r[maxm],q[maxm]; /********************************* Segment Tree - st *********************************/
struct Node{
int l,r;
int val,lazy;
void update(int x)
{
val|=x;
lazy|=x;
}
}node[*maxn];
void pushdown(int root)
{
if(node[root].lazy)
{
node[root*].update(node[root].lazy);
node[root*+].update(node[root].lazy);
node[root].lazy=;
}
}
void pushup(int root)
{
node[root].val=node[root*].val&node[root*+].val;
}
void build(int root,int l,int r) //对区间[l,r]建树
{
node[root].l=l; node[root].r=r;
node[root].val=; node[root].lazy=;
if(l==r) node[root].val=;
else
{
int mid=l+(r-l)/;
build(root*,l,mid);
build(root*+,mid+,r);
pushup(root);
}
}
void update(int root,int st,int ed,int val)
{
if(st>node[root].r || ed<node[root].l) return;
if(st<=node[root].l && node[root].r<=ed) node[root].update(val);
else
{
pushdown(root);
update(root*,st,ed,val);
update(root*+,st,ed,val);
pushup(root);
}
}
int query(int root,int st,int ed)
{
if(st>node[root].r || ed<node[root].l) return (<<)-;
if(st<=node[root].l && node[root].r<=ed) return node[root].val;
else
{
pushdown(root);
int ls=query(root*,st,ed);
int rs=query(root*+,st,ed);
pushup(root);
return ls&rs;
}
}
/********************************* Segment Tree - ed *********************************/ int main()
{
scanf("%d%d",&n,&m);
build(,,n);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&l[i],&r[i],&q[i]);
update(,l[i],r[i],q[i]);
} bool ok=;
for(int i=;i<=m;i++)
{
if(query(,l[i],r[i])!=q[i]) {
ok=; break;
}
}
printf("%s\n",ok?"YES":"NO");
if(ok) for(int i=;i<=n;i++) printf("%d%c",query(,i,i),i<n?' ':'\n');
}
E - Game with Strings - [期望+状压DP]
You play the game with your friend. The description of this game is listed below.
Your friend creates $n$ distinct strings of the same length $m$ and tells you all the strings. Then he randomly chooses one of them. He chooses strings equiprobably, i.e. the probability of choosing each of the $n$ strings equals $\frac{1}{n}$. You want to guess which string was chosen by your friend.
In order to guess what string your friend has chosen, you are allowed to ask him questions. Each question has the following form: «What character stands on position $pos$ in the string you have chosen?» A string is considered guessed when the answers to the given questions uniquely identify the string. After the string is guessed, you stop asking questions.
You do not have a particular strategy, so as each question you equiprobably ask about a position that hasn't been yet mentioned. Your task is to determine the expected number of questions needed to guess the string chosen by your friend.
Input
The first line contains a single integer $n (1 \le n \le 50)$ — the number of strings your friend came up with.
The next $n$ lines contain the strings that your friend has created. It is guaranteed that all the strings are distinct and only consist of large and small English letters. Besides, the lengths of all strings are the same and are between $1$ to $20$ inclusive.
Output
Print the single number — the expected value. Your answer will be considered correct if its absolute or relative error doesn't exceed $10^{-9}$.
Examples
Input
2
aab
aac
Output
2.000000000000000
Input
3
aaA
aBa
Caa
Output
1.666666666666667
Input
3
aca
vac
wqq
Output
1.000000000000000
题意:
给出 $n$ 个等长 $m$ 的字符串,对方会等可能地选择其中一个字符串,我不知道他选择了哪个,所以每次会等可能地询问对方某个位置上是什么字符。
一旦能够唯一确定是哪个字符串,我就停止询问。求我询问次数的期望。
题解:
假设 $dp[sta]$ 表示进行 $sta$ 状态询问的概率,这样一来,要完成状态转移,必须要知道在进行该状态的询问后是否已经确定对方选定的串。
如果已经确定对方选定的串,那么我们就不需要再询问了;否则还要再询问一个位置,那么这个多一次的询问,对于整个询问数目的期望的贡献就为 $dp[sta] \times 1$。
我们可以使用 $f[same]$ 来表示 $same$ 状态的位置上字符全部相同的字符串有哪些。然后我们发现,$f[same]$ 也是可以用dp求出来的,一开始我们 $O(n^2)$ 地求出初始条件:对于任意两个字符串 $i,j(i<j)$,他们所有的同位置上相同的字符可表示成状态 $same$($1$ 表示相同,$0$ 表示不同),即有初始条件 $f[same]=(1<<i)|(1<<j)$。其后我们可以dp求出全部的 $f[same]$,如果 $same_1$ 状态包含$same_2$ 状态,那么 $same_1$ 状态下不能区分的字符串在 $same_2$ 状态下一样无法区分。
接下来考虑如何根据 $dp[sta]$ 求期望,$f[sta]$ 里有 $k$ 个 $1$ 代表有 $k$ 个串尚不能分辨,那么对于询问这 $k$ 个串其中一个,询问期望就是 $dp[sta]×1$,其他0的位置就是已经不需要询问了,1的位置这次询问是这次必须的,之后还询问不询问不知道,还询问不询问是后面的状态所决定的,对于 $k$ 个询问次数期望就是 $dp[sta] \times k$,对于最后的答案自然是加 $dp[sta] \times k / n$。其实主要思想就是利用期望的可加性,分开来算。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
const int maxm=; int n,m;
char s[maxn][maxm];
double dp[<<];
ll f[<<];
inline int cntbit(int x){return x?(x&)+cntbit(x>>):;}
int main()
{ scanf("%d",&n);
for(int i=;i<n;i++) scanf("%s",s[i]);
m=strlen(s[]); //f[same]初始化
memset(f,,sizeof(f));
for(int i=;i<n;i++)
{
for(int j=i+;j<n;j++)
{
int same=;
for(int k=;k<m;k++) {
if(s[i][k]==s[j][k]) same|=(<<k);
}
f[same]|=(1LL<<j)|(1LL<<i);
}
} //dp求所有的f[same]
for(int same=(<<m)-;same>=;same--)
{
for(int i=;i<m;i++) {
if(same&(<<i)) f[same^(<<i)]|=f[same];
}
} double ans=;
memset(dp,,sizeof(dp)); dp[]=;
for(int sta=;sta<(<<m);sta++)
{
if(f[sta]==) continue; int cnt=cntbit(sta);
for(int i=;i<m;i++)
{
if(sta&(<<i)) continue;
dp[sta|(<<i)]+=dp[sta]/(m-cnt);
} for(int i=;i<n;i++) {
if(f[sta]&(1LL<<i)) ans+=dp[sta];
}
} printf("%.10f\n",ans/n);
}
说实话,这题为什么这么求期望我还是云里雾里的……应该是我飘了,期望和概率题也敢碰了……
Codeforces 483 - A/B/C/D/E - (Done)的更多相关文章
- Codeforces Round #483 (Div. 2) B题
B. Minesweeper time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Codeforces Round #483 (Div. 2)C题
C. Finite or not? time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Codeforces Round #483 (Div. 2) [Thanks, Botan Investments and Victor Shaburov!]
题目链接:http://codeforces.com/contest/984 A. Game time limit per test:2 seconds memory limit per test:5 ...
- Codeforces Round #483 (Div. 2) B. Minesweeper
题目地址:http://codeforces.com/contest/984/problem/B 题目大意:扫雷游戏,给你一个n*m的地图,如果有炸弹,旁边的八个位置都会+1,问这幅图是不是正确的. ...
- Codeforces Round #483 (Div. 2) C. Finite or not?
C. Finite or not? time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Codeforces Round #483 (Div. 2) D. XOR-pyramid
D. XOR-pyramid time limit per test 2 seconds memory limit per test 512 megabytes input standard inpu ...
- Codeforces Round #483 (Div. 2)
题目链接: https://cn.vjudge.net/contest/229761 A题: n个数字,两个人轮流去数字,直到剩下最后一个数字为止,第一个人希望剩下的数字最小,第二个人希望数字最大,最 ...
- Codeforces Round #483 Div. 1
A:首先将p和q约分.容易发现相当于要求存在k满足bk mod q=0,也即b包含q的所有质因子.当然不能直接分解质因数,考虑每次给q除掉gcd(b,q),若能将q除至1则说明合法.但这个辣鸡题卡常, ...
- Codeforces Round #483 (Div. 2)题解
A. Game time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...
随机推荐
- Guava Preconditions 工具参数前置校验
guava 提供 Preconditions 作为代码校验的工具类,用来简化开发中对代码的校验或预处理,在逻辑开始前进行合理性校验,避免参数传入过深导致的数据错误. 并且能够在不符合校验条件的地方, ...
- 通过__block的作用深入研究block
block普通引用 默认情况下,在block中访问外部变量是通过复制一个变量来操作的,既可以读,但是写操作不对原变量生效,下面通过代码来举证 NSString *a = @"testa&qu ...
- Rabbit五种消息队列学习(二) – 简单队列
队列结构图 P:消息的生产者 C:消息的消费者 红色:队列 生产者将消息发送到队列,消费者从队列中获取消息. 测试 1.连接MQ public static Connection getConnect ...
- 理解JAVA的IO
1. 什么是流Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序列 ...
- 【Apache】Apache的安装和配置
Apache是世界非常流行的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一. Apache在Win7上的安装 下载apa ...
- 生产环境CPU过高问题定位
问题描述: 生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 解决过程: 1.根据top命令,发现 ...
- 使用phpstorm进行PHP断点调试
PHP开发中都说一个会偷懒的程序员才是合格的程序员,在PHP开发中调试是必须要有的,可能要重复很多次的去调试,一次又一次,今天我们就来教教大家如何偷懒的,那么就来讲讲使用phpstorm进行偷懒吧! ...
- ANTLR v4 权威参考笔记(目录)
ANTLR v4是一款强大的语法分析器生成器,可以用来读取.处理.执行和转换结构化文本或二进制文件.通过称为文法的形式化语言描述,ANTLR可以为该语言自动生成词法分析器.生成的语法分析器可以自动构建 ...
- CUDA编程之快速入门
CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架构.做图像视觉领域的同学多多少少都会接触到CUDA,毕竟要做性能速度优化,CUDA是个很重要 ...
- OLT、分光器、ONU直接的关系