BestCoder Round #73(div.2)
2016-02-21 13:54
337 查看
比赛链接:click here
Accepts: 393
Submissions: 548
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
输入描述
输出描述
输入样例
输出样例
【思路】:
首先,如果先对偶数行取反,再对偶数列取反,可以得到一个[n/2]
+ [m/2][n/2]+[m/2](下取整)的解,
只要说明这个这是答案的下界就可以了。 考虑第一列,每次操作最多使得两个第一列的相邻元素变得一样, 第一列有n-1n−1对相邻元素,这样使得第一列变成一样的次数就是[(n-1)/2][(n−1)/2](上取整),同理考虑第一行即可。
代码:
Accepts: 123
Submissions: 525
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
输入描述
输出描述
输入样例
输出样例
【思路】:
让 nn 个点联通最少需要 n-1n−1 条边,所以最多只能删除两条边,我们可以枚举删除的这两条边(或者唯一的一条边),然后暴力BFS判断连通性就好了。时间复杂度 O(n^3)O(n3)。
代码:
Accepts: 2
Submissions: 22
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
输入描述
输出描述
输入样例
输出样例
Hint
【思路】:
很明显这是一道数位DP的题目,状态 dp[i][j][k]dp[i][j][k] 表示当前考虑了最高的 ii 位,两个数目前数位和的差是 jj,当前两个数以及给定的 nn之间的大小关系是 kk,然后暴力枚举这两个数的当前位的值,然后转移就好了。时间复杂度 O(\log^2
n)O(log2n)。
待补~~
Accepts: 0
Submissions: 8
Time Limit: 3000/1500 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
输入描述
输出描述
输入样例
输出样例
Hint
【思路】:
这是一道没什么思维含量的题,但是细节比较多。
首先答案不超过 nn,因为我们可以直接在原来平均数的位置加入 nn 个数,这样中位数就等于平均数了。
其次,答案满足二分性(指第一问),因为如果存在加入 ii 个数的方案,我们可以把多出来的数都放在当前平均数的位置,显然还是满足要求的。
所以我们可以先二分答案,这样问题就转化成了加入 KK 个数,在满足平均数小于等于中位数的同时最小化平均数。
可以发现最开始给出的 nn 个数把 [1,m][1,m] 分成了 n+1n+1 个区间,我们可以枚举中位数在哪一个区间内,当然这儿要进行分类讨论,大致的情况有这么多种:
1.总数是奇数,中位数是原来给出的数。
2.总数是奇数,中位数是加入的数。
3.总数是偶数,中位数是原来给出的两个数的平均数。
4.总数是偶数,中位数是一个加入的数和一个比它大的原来给出的数的平均数。
5.总数是偶数,中位数是一个加入的数和一个比它小的原来给出的数的平均数。
6.总数是偶数,中位数是两个新加入的数的平均数。
对于每种情况,我们可以把中位数设为 xx,然后直接贪心,这样就能得到一个方程,解出这个方程然后再判断解是否合法并更新答案就行了。(当然,如果再加思考的话可以发现上述情况并不是都需要考虑,有两个是不会影响答案的)
时间复杂度 O(n \log n)O(nlogn)
待补~~
Accepts: 5
Submissions: 66
Time Limit: 16000/8000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
输入描述
输出描述
输入样例
输出样例
【思路】:
注意到10^7107之内的数最多phi O(log(n))O(log(n)) 次就会变成11,
因此可以考虑把一段相同的不为11的数缩成一个点,用平衡树来维护。每次求phi的时候就在平衡树上取出这个区间然后暴力求phi,如果一段数变成了11,就在平衡树里面删掉它,最后统计答案的时候只要把区间中被删去的11加回答案即可,时间复杂度O((n
+ m)logn)O((n+m)logn)
待补~~(平衡树:它是一
棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。构造与调整方法 平衡二叉树的常用算法有红黑树、***L、Treap等。
最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。)
Rikka with Chess
Accepts: 393Submissions: 548
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
一个n \times mn×m的黑白相间的棋盘,每次可以选择一个矩形把其中的所有格子反色。问把所有格子变成一种颜色时的最少操作次数。
输入描述
第一行一个整数 T(T \leq 10)T(T≤10) 表示数据组数。 每组数据有一行, 两个正整数 n,m(n \leq 10^9, m \leq 10^9)n,m(n≤109,m≤109)。
输出描述
对于每组数据输出一行一个整数,代表最少需要的操作次数。
输入样例
3 1 2 2 2 3 3
输出样例
1 2 2
【思路】:
首先,如果先对偶数行取反,再对偶数列取反,可以得到一个[n/2]
+ [m/2][n/2]+[m/2](下取整)的解,
只要说明这个这是答案的下界就可以了。 考虑第一列,每次操作最多使得两个第一列的相邻元素变得一样, 第一列有n-1n−1对相邻元素,这样使得第一列变成一样的次数就是[(n-1)/2][(n−1)/2](上取整),同理考虑第一行即可。
代码:
/* Problem:BC#73 Rikka with Chess Author :javaherongwei Runtime:0ms Language: G++ Result :Accepted */ #include<stdio.h> int main() { int i,j,k,t,n,m,ans; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); printf("%d\n",n/2+m/2); } return 0; }
Rikka with Graph
Accepts: 123Submissions: 525
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 给出一张 nn 个点 n+1n+1 条边的无向图,你可以选择一些边(至少一条)删除。 现在勇太想知道有多少种方案使得删除之后图依然联通。 当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
第一行一个整数表示数据组数 T(T \leq 30)T(T≤30)。 每组数据的第一行是一个整数 n(n \leq 100)n(n≤100)。 接下来 n+1n+1 行每行两个整数 u,vu,v 表示图中的一条边。
输出描述
对每组数据输出一行一个整数表示答案。
输入样例
1 3 1 2 2 3 3 1 1 3
输出样例
9
【思路】:
让 nn 个点联通最少需要 n-1n−1 条边,所以最多只能删除两条边,我们可以枚举删除的这两条边(或者唯一的一条边),然后暴力BFS判断连通性就好了。时间复杂度 O(n^3)O(n3)。
代码:
/* Problem:BC#73 Rikka with Graph Author :javaherongwei Runtime:296ms Language: G++ Result :Accepted */ #pragma comment(linker,"/STACK:102400000,102400000") #include <iostream> #include <stdio.h> #include <stdlib.h> #include <cassert> #include <climits> #include <ctime> #include <numeric> #include <vector> #include <algorithm> #include <bitset> #include <math.h> #include <string.h> #include <iomanip> #include <complex> #include <deque> #include <functional> #include <list> #include <map> #include <string> #include <sstream> #include <set> #include <stack> #include <queue> using namespace std; template<class T> inline T sqr(T x) { return x * x; } typedef long long LL; typedef unsigned long long ULL; typedef long double db; typedef pair<int, int> PII; typedef pair<PII, int> PIII; typedef pair<LL, LL> PLL; typedef pair<LL, int> PLI; typedef pair<db, db> PDD; #define MP make_pair #define PB push_back #define sz(x) ((int)(x).size()) #define mem(ar,val) memset(ar, val, sizeof(ar)) #define istr stringstream #define FOR(i,n) for(int i=0;i<(n);++i) #define forIt(mp,it) for(__typeof(mp.begin()) it = mp.begin();it!=mp.end();it++) const double EPS = 1e-6; const int INF = 0x3fffffff; const LL LINF = INF * 1ll * INF; const double PI = acos(-1.0); const int maxn = 1e5+10; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define lowbit(u) (u&(-u)) using namespace std; #define LETTER 26 #define lowbit(a) a&-a int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}}; int dir6[6][3]= {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};///六个方向 int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}}; inline LL read() { int c=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} return c*f; } int a[maxn],b[maxn],c[maxn]; char s1[maxn],s2[maxn]; struct node { int u,v; } edge[maxn]; int n; int fa[maxn]; int Find(int x) { return x==fa[x]?x:fa[x]=Find(fa[x]); } int solve(int a,int b) { for(int i=1; i<=n; ++i) fa[i]=i; for(int i=1; i<=n+1; ++i) { if(i==a|| i==b) continue; int uu=Find(edge[i].u),vv=Find(edge[i].v); if(uu!=vv) fa[uu]=vv; } int sum=0; for(int i=1; i<=n; i++) { if(fa[i]==i) { sum++; if(sum>1) return false; } } return true; } int main() { int t; t=read(); while(t--) { int ret=0; n=read(); for(int i=1; i<=n+1; ++i) scanf("%d%d",&edge[i].u,&edge[i].v); for(int i=1; i<=n+1; ++i) for(int j=i; j<=n+1; ++j) ret+=solve(i,j); printf("%d\n",ret); } return 0; }
Rikka with Array
Accepts: 2Submissions: 22
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 有一个长度为 nn 的数组 AA(下标为 11 到 nn),A_iAi 为 ii 的二进制表示中的1的个数,例如 A[1]=1, A[3]=2, A[10]=2A[1]=1,A[3]=2,A[10]=2。 现在勇太想知道数组 AA 中满足 A[i]>A[j]A[i]>A[j] 的数对 (i,j)(1 \leq i < j \leq n)(i,j)(1≤i<j≤n) 的个数。 当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
第一行一个整数表示数据组数 T(T \leq 10)T(T≤10)。 每组数据第一行一个整数表示 n(n \leq 10^{300})n(n≤10300)
输出描述
对于每组数据输出一行一个整数表示答案,因为答案可能很大,你只需要输出答案对 998244353998244353 取模之后的结果。
输入样例
1 10
输出样例
7
Hint
当 n=10n=10 的时候,数组 AA 为 1,1,2,1,2,2,3,1,2,21,1,2,1,2,2,3,1,2,2。 答案为7。
【思路】:
很明显这是一道数位DP的题目,状态 dp[i][j][k]dp[i][j][k] 表示当前考虑了最高的 ii 位,两个数目前数位和的差是 jj,当前两个数以及给定的 nn之间的大小关系是 kk,然后暴力枚举这两个数的当前位的值,然后转移就好了。时间复杂度 O(\log^2
n)O(log2n)。
待补~~
Rikka with Sequence
Accepts: 0Submissions: 8
Time Limit: 3000/1500 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 有一个长度为 nn 的整数数组 AA,AA中每一个数都在区间 [1,m][1,m] 中。现在你需要加入最少数量的数使得 AA 的平均数小于等于中位数(加入的数可以是实数)。 加入的数必须在 [1,m][1,m] 之间 现在勇太想知道最少需要加入多少个数,以及在最小化加入数的个数的基础上,平均数最小能是多少。 当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
第一行一个整数 T(T \leq 1000)T(T≤1000) 表示数据组数,其中 n > 100n>100 的数据不超过 55 组。 每组数据第一行两个整数 n,m(n \leq 10^5,m \leq 10^9)n,m(n≤105,m≤109)。 接下来一行 nn 个整数描述数组 AA。
输出描述
对于每组数据输出一行两个数,第一个数表示最少添加的数字的数量,第二个数表示最小的平均数(保留三位小数)。
输入样例
1 3 5 1 2 5
输出样例
1 3.000
Hint
只需要加入数字 4.0004.000 就能满足条件。
【思路】:
这是一道没什么思维含量的题,但是细节比较多。
首先答案不超过 nn,因为我们可以直接在原来平均数的位置加入 nn 个数,这样中位数就等于平均数了。
其次,答案满足二分性(指第一问),因为如果存在加入 ii 个数的方案,我们可以把多出来的数都放在当前平均数的位置,显然还是满足要求的。
所以我们可以先二分答案,这样问题就转化成了加入 KK 个数,在满足平均数小于等于中位数的同时最小化平均数。
可以发现最开始给出的 nn 个数把 [1,m][1,m] 分成了 n+1n+1 个区间,我们可以枚举中位数在哪一个区间内,当然这儿要进行分类讨论,大致的情况有这么多种:
1.总数是奇数,中位数是原来给出的数。
2.总数是奇数,中位数是加入的数。
3.总数是偶数,中位数是原来给出的两个数的平均数。
4.总数是偶数,中位数是一个加入的数和一个比它大的原来给出的数的平均数。
5.总数是偶数,中位数是一个加入的数和一个比它小的原来给出的数的平均数。
6.总数是偶数,中位数是两个新加入的数的平均数。
对于每种情况,我们可以把中位数设为 xx,然后直接贪心,这样就能得到一个方程,解出这个方程然后再判断解是否合法并更新答案就行了。(当然,如果再加思考的话可以发现上述情况并不是都需要考虑,有两个是不会影响答案的)
时间复杂度 O(n \log n)O(nlogn)
待补~~
Rikka with Phi
Accepts: 5Submissions: 66
Time Limit: 16000/8000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
给出一个长度为nn的数组AA,接下来有mm次操作。 1 \; l \; r1lr 对所有区间[l,r][l,r]中的整数ii,把A_iAi变成\varphi(A[i])φ(A[i])(指欧拉函数) 2 \; l \; r \; x2lrx 对所有区间[l,r][l,r]中的整数ii,把A[i]A[i]变成xx 3 \; l \; r3lr 询问[l,r][l,r]的区间和。
输入描述
第一行一个整数 T(T \leq 100)T(T≤100) 表示数据组数,其中 n > 10^5n>105 的数据不超过 22 组。 每组数据第一行两个整数 n,m(n \leq 3 \times 10^5, m \leq 3 \times 10^5)n,m(n≤3×105,m≤3×105)。 接下来一行 nn 个整数描述数组 AA。 接下来mm行, 每行若干个整数表示一次操作。 保证在任意时刻 1 \leq A[i] \leq 10^71≤A[i]≤107。
输出描述
对于每一次询问输出一行,代表这个询问操作的答案。
输入样例
1 10 10 56 90 33 70 91 69 41 22 77 45 1 3 9 1 1 10 3 3 8 2 5 6 74 1 1 8 3 1 9 1 2 10 1 4 9 2 8 8 69 3 3 9
输出样例
80 122 86
【思路】:
注意到10^7107之内的数最多phi O(log(n))O(log(n)) 次就会变成11,
因此可以考虑把一段相同的不为11的数缩成一个点,用平衡树来维护。每次求phi的时候就在平衡树上取出这个区间然后暴力求phi,如果一段数变成了11,就在平衡树里面删掉它,最后统计答案的时候只要把区间中被删去的11加回答案即可,时间复杂度O((n
+ m)logn)O((n+m)logn)
待补~~(平衡树:它是一
棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。构造与调整方法 平衡二叉树的常用算法有红黑树、***L、Treap等。
最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。)
相关文章推荐
- oracle SQL优化之高效的函数调用
- hrbust 哈理工oj 1352 中间的球【floyd递推关系过】
- 如何让minicom换行
- 如何让minicom换行
- 我的小感
- 快速掌握Lua 5.3 —— 字符串库 (2)
- 如何让minicom换行
- hadoop1.2.1三种模式配置
- Android 一键打造仿IOS右滑退出Activity,非常简单的集成方式(SwipeFinishLayout)
- Educational Codeforces Round 8 D. Magic Numbers 数位DP
- AnguarJS 第一天----Hello World
- 颜色代码
- 单片机系列知识2--存储器(1)
- 【BZOJ 1036】【ZJOI 2008】树的统计 树链剖分模板题
- 验证码及验证码透明的背景
- django个人总结
- tomcat发布web service教程
- 新建MAVEN工程,JSP页面报The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- Android Studio和IntelliJIODEA运行Android项目遇到Cannot reload AVD list: cvc-enumeration-valid: Value '280dp
- Android开发学习之路--百度地图之初体验