Educational Codeforces Round 80 (Rated for Div. 2)D E
D枚举子集
题:https://codeforces.com/contest/1288/problem/D
题意:给定n个序列,每个序列m个数,求第i个和第j个序列组成b序列,b序列=max(a[i][k],a[j][k]),使得b序列最小值最大化,求达成条件的 i 和 j (i可等于j)
分析1:因为m<=8,所以我们考虑对每个序列的m个数进行状压。
这题的状压是,“1”状态,表示取max取到了这个位置,“0”就表示max没取到这个位置。
因为题目要求很明确,要b序列最小值最大化,所以我们不用考虑取max后哪个数覆盖哪个数,只需考虑最小值应该是第几个序列即可。
然后就对应俩个序列进行最大化匹配即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
const int inf=0x3f3f3f3f;
const ll INF=1e18;
const int M=1e3+;
int a[];
int maxx[M],maxid[M];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++)
scanf("%d",&a[j]);
for(int j=;j<(<<m);j++){
int minn=inf;
for(int k=;k<m;k++){
if(j&(<<k))
minn=min(minn,a[k+]);
}
if(minn>=maxx[j]){
maxx[j]=minn;
maxid[j]=i;
}
}
}
int ans=-,x,y;
for(int i=;i<(<<m);i++){
if(ans<min(maxx[i],maxx[(<<m)--i])){
ans=min(maxx[i],maxx[(<<m)--i]);
x=maxid[i];
y=maxid[(<<m)--i];
}
}
printf("%d %d",x,y);
return ;
}
分析2:二分答案,将满足条件的位置用状压记录下来更新即可。
#include<bits/stdc++.h>
using namespace std;
int ansi,ansj,limit;
const int N=1e3+;
const int M=3e5+;
int a[M][],pos[N],p[];
int n,m;
bool check(int x){
for(int i=;i<=limit;i++)
pos[i]=;
for(int i=;i<=n;i++){
int now=;
for(int j=;j<=m;j++)
if(a[i][j]>=x)
now|=p[j];
pos[now]=i;///状态now由第i个序列得来
}
for(int i=;i<=limit;i++)
for(int j=i;j<=limit;j++){
if((i|j)==limit&&pos[i]&&pos[j]){
return ansi=pos[i],ansj=pos[j],true;
}
}
return false;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&a[i][j]);
limit=(<<m)-;
for(int i=;i<=m;i++){
p[i]=<<(i-);
}
int l=,r=1e9;
while(l<=r){
int midd=(l+r)>>;
if(check(midd))
l=midd+;
else
r=midd-;
}
printf("%d %d\n",ansi,ansj);
return ;
}
E BIT
题:https://codeforces.com/contest/1288/problem/E
题意:对于从1~n的一个序列,给定m个操作,每个操作给定一个数x,含义为将x提到序列的第一个位置,问每个数可能的最小最大位置是多少
分析:最小位置俩种可能,有被操作过答案就是1,否则就是本身数值,至于最大值,我们考虑事先考虑将n个数挪后m+1个位置(因为最多m个操作),目的是留出m个位置给要提出来的数;
然后我每次提出来一个数就统计一下这个数前面有多少个 数,取max之后BIT更新一下,一直重复m步操作。
#include<bits/stdc++.h>
using namespace std;
const int M=1e6+;
int pos[M],minn[M],maxx[M],tr[M];
void add(int x,int c){
while(x<M)
tr[x]+=c,x+=(x&-x);
}
int Sum(int x){
int ans=;
while(x)
ans+=tr[x],x-=(x&-x);
return ans;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
pos[i]=m++i;
minn[i]=maxx[i]=i;
add(pos[i],);
}
int nowpos=m+;
while(m--){
int x;
scanf("%d",&x);
minn[x]=;
int num=Sum(pos[x]);
maxx[x]=max(maxx[x],num);
add(pos[x],-);///消除这个位置的标记
pos[x]=nowpos--;
add(pos[x],);
}
for(int i=;i<=n;i++){
int num=Sum(pos[i]);
maxx[i]=max(maxx[i],num);
}
for(int i=;i<=n;i++)
printf("%d %d\n",minn[i],maxx[i]);
return ;
}
Educational Codeforces Round 80 (Rated for Div. 2)D E的更多相关文章
- Educational Codeforces Round 80 (Rated for Div. 2)
A. Deadline 题目链接:https://codeforces.com/contest/1288/problem/A 题意: 给你一个 N 和 D,问是否存在一个 X , 使得 $x+\lce ...
- Educational Codeforces Round 80 (Rated for Div. 2) E. Messenger Simulator
可以推出 min[i]要么是i要么是1,当a序列中存在这个数是1 max[i]的话就比较麻烦了 首先对于i来说,如果还没有被提到第一位的话,他的max可由他后面的这部分序列中 j>=i 的不同数 ...
- Educational Codeforces Round 80 (Rated for Div. 2)部分题解
A. Deadline 题目链接 题目大意 给你\(n,d\)两个数,问是否存在\(x\)使得\(x+\frac{d}{x+1}\leq n\),其中\(\frac{d}{x+1}\)向上取整. 解题 ...
- Educational Codeforces Round 80 (Rated for Div. 2)(A-E)
C D E 这三道题感觉挺好 决定程序是否能通过优化在要求的时间内完成,程序运行时间为t,你可以选择花X天来优化,优化后程序的运行时间为t/(x+1)取上整,花费的时间为程序运行时间加上优 ...
- Educational Codeforces Round 80 (Rated for Div. 2)E(树状数组,模拟,思维)
#define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ],mx[],a[],pos[],sum ...
- Educational Codeforces Round 80 (Rated for Div. 2)D(二分答案,状压检验)
这题1<<M为255,可以logN二分答案后,N*M扫一遍表把N行数据转化为一个小于等于255的数字,再255^2检验答案(比扫一遍表复杂度低),复杂度约为N*M*logN #define ...
- Educational Codeforces Round 80 (Rated for Div. 2)C(DP)
#define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ; ][],temp[][]; int ...
- Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship
Problem Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...
- Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)
Problem Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...
随机推荐
- 7 ~ express ~ body-parser 模块的使用
一,安装 : npm install body-parser 二,加载 : var bodyParser = require('body-parser') 三,配置 : https://github. ...
- UVALive 5913 字典树
先输入n个字符串的字典,每个字符串的前缀+后缀可以组成新的合法字符串,但肯定是有重复的,问从给定的字符串,生成的所有可能的字符串为多少个 把前缀和后缀压入字典树,达到前缀和后缀的去重,首先的总和即为前 ...
- MessageBox.Show的使用
MessageBox.Show("内容","标题") // 摘要:// 使用指定的帮助文件.HelpNavigator 和帮助主题显示一个具有指定文本.标题.按 ...
- 洛谷 P2719 搞笑世界杯
题目传送门 解题思路: f[i][j]表示买i张A票,j张B票的概率. AC代码: #include<iostream> #include<cstdio> using name ...
- 洛谷 AT2827 LIS
题目传送门 解题思路: 用f[i]表示长度为i的最长上升子序列的最小的末尾. AC代码: #include<iostream> #include<cstdio> #includ ...
- C++保存数据到CSV文件
主要是今天工作的时候需要把一些数据保存到本地,因为是一些预测值和标签的对比,还有预测值的概率,所以想到用CSV文件来保存,大概查了一下,还是比较简单的,所以记录一下. 首先要说明的是CSV文件有点类似 ...
- page-break-before和page-break-after 实现分页打印
page-break-before和page-break-after CSS属性并不会修改网页在屏幕上的显示,这两个属性是用来控制文件的打印方式.每个打印属性都可以设定4种设定值:auto.alway ...
- 文献阅读报告 - Social LSTM:Human Trajectory Prediction in Crowded Spaces
概览 简述 文献所提出的模型旨在解决交通中行人的轨迹预测(pedestrian trajectory prediction)问题,特别是在拥挤环境中--人与人交互(interaction)行为常有发生 ...
- SQL基础教程(第2版)第3章 聚合与排序:3-1 对表进行聚合查询
3-1 对表进行聚合查询 ● 使用聚合函数对表中的列进行计算合计值或者平均值等的汇总操作.● 通常,聚合函数会对NULL以外的对象进行汇总.但是只有COUNT函数例外,使用COUNT(*)可以查出包含 ...
- 对PHP-GC(垃圾回收)的一点理解
一直对php的垃圾回收机制不明不白故自己开贴记录下. 首先,说到垃圾回收,得先知道什么情况下才能产生垃圾. 如果一个变量refcount在增加,说明在被使用,不是垃圾. 如果一个变量的refcount ...