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 ...
随机推荐
- JavaScript 同步异步示意图
- 【Linux】磁盘读写 测试
一.如何查看当前磁盘的IO使用情况 使用命令:iotop Total DISK READ: 3.89 K/s | Total DISK WRITE: 0.00 B/s TID PRIO USER DI ...
- k8s dev
0. install golang 1.9.1 https://golang.org/doc/install 1. development.md https://github.com/kubernet ...
- 【资料下载区】【iCore1S相关代码、资料下载地址】更新日期2017/10/09
[iCore1S相关文档][更新中...] iCore1S原理图(PDF)下载iCore1S引脚注释(PDF)下载 [iCore1S相关例程代码][ARM][更新中...] DEMO1.0测试程序发布 ...
- C#作为客户端调用gsoap生成的C++服务端
近日在学习C++,偶然遇到网友想用C#调用gsoap生成的C++服务的问题,遂决定研究一下,网上搜索了很久,大多数是C++调用C#的应用.... 经过本人的不断努力,终于找到一种解决问题的方法,总结如 ...
- Linux 环境变量_006
***Linux 环境变量指系统运行程序或命令的能快速找到其位置等其它功能,不用输入复杂命令.以$PATH环境变量为例子, $PATH决定了shell指定寻找命令或程序的路径,比较执行ls命令,如果没 ...
- is not in the sudoers file解决方法
用sudo时提示"xxx is not in the sudoers file. This incident will be reported.其中XXX是你的用户名,也就是你的用户名没有权 ...
- 5迪米特法则LoD
一.什么是迪米特法则 迪米特法则(Law of Demeter )又叫做最少知识 原则,也就是说,一个对象应当对其他对象尽可 能少的了解. 迪米特法则最初是用来作为面向对象的系统设 计风格的一种法则, ...
- mysql 游标 demo
一.MySQL游标的概念 1.游标介绍 MySQL的游标(cursor)是一个重要的概念,通过查找资料与自己的理解,主要得出以下几点关于自己的理解. 有数据缓冲的思想:游标的设计是一种数据缓冲区的思想 ...
- String 类型的值能够被反射改变从而引发的意外事件
今天刷技术文章,遇到了一个问题,用 Java 反射机制去修改 String 变量的值,出于深入研究,就发现了一个问题,即,用初始值比较修改后的值,用 == or .equals() 方法,出现了相等的 ...