https://www.xoj.red/contests/show/1231

下面会写一些题目的解析什么的,当然不会粘贴题目只是简单提一下

(部分题目简单的题目就不概括了)

其实难度应该前面比较低.

问题A: 3894: Out of Sorts

本题求出冒泡排序需要几趟。

考虑一次冒泡排序的交换,减小对应1个位子上的1个逆序对。

但是对于每一个位子所需要减小的逆序对数量是不一样的。

对于每一趟,消去每一个位子上1个逆序对
所以趟数就是每个位子上的数产生逆序对数的最大值。

最后的+1指的是即使上一次已经消除所有逆序对了,我们并不知道数组有序了,所以判断最后一遍查看是否有序。

考虑树状数组维护$O(n log_2 n)$

和善的树状数组代码如下:

# include <bits/stdc++.h>
using namespace std;
const int N=1e5+;
int a[N],tmp[N],c[N];
int n,T;
void update(int x){for (;x<=n;x+=x&-x)c[x]++;}
int query(int x){int ret=;for (;x;x-=x&-x) ret+=c[x];return ret;}
int main()
{
scanf("%d",&n); tmp[]=n;
for (int i=;i<=n;i++) scanf("%d",&a[i]),tmp[i]=a[i];
sort(tmp+,tmp+tmp[]+);
T=unique(tmp+,tmp++tmp[])-tmp-;
int ans=;
for (int i=;i<=n;i++) {
int w=lower_bound(tmp+,tmp++T,a[i])-tmp;
update(w);
ans=max(i-query(w),ans);
}
printf("%d\n",ans+);
return ;
}

问题A: 3894: Out of Sorts

问题B: 3895: Lemonade Line

考虑一个简单的贪心,每次选择当前等待奶牛数目最多的一个,占用等待奶牛数少的奶牛的位置。

如果不是这样做,对答案会有正贡献,是我们不期望的,与答案最优性矛盾,我们选择一个一定是最优的决策。

# include <bits/stdc++.h>
using namespace std;
const int N=1e5+;
int n,a[N];
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
sort(a+,a++n);
int cnt=,Ans=;
for (int i=n;i>=;i--) {
if (cnt<=a[i])Ans++,cnt++;
else break;
}
printf("%d\n",Ans);
return ;
}

问题B: 3895: Lemonade Line

问题C: 3896: Multiplayer Moo

大概是不存在一个正解的。

问题D: 3897: Out of Sorts

考虑这样一个事情,如果正反来了一边那么每一次对于i位置上的数a[i]来说他左边位置j $\in $ [1,i-1]比a[i]严格大的数有一个被放到了i的右边

他右边的位置j$\in $ [i+1,n]比a[i]严格小的数有一个被放到了i的左边。当且仅当a[i]左边和右边不存在上述的数那么停止。

如果把一个数组变为有序显然第i个位子上放置第i大的数。

显然他们的位置一定在i位置后面。所有至少需要移动这么多次,把每一个比i大的数移动到i的右面。

显然我们冒泡1次对于每个i对应的有多少数在他左边只能减少1个这样的数,所以答案就是max{前i个数里面有多少个数字离散化后是比i大的,1}

# include <bits/stdc++.h>
using namespace std;
const int N=1e5+;
int c[N],n;
struct rec{int x,id;}a[N];
bool cmp(rec a,rec b)
{
if (a.x!=b.x) return a.x<b.x;
return a.id<b.id;
}
void update(int x){for (;x<=n;x+=x&-x) c[x]++;}
int query(int x){int ret=; for (;x;x-=x&-x) ret+=c[x]; return ret;}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&a[i].x),a[i].id=i;
sort(a+,a++n,cmp);
int ans=;
for (int i=;i<=n;i++){
update(a[i].id);
ans=max(ans,i-query(i));
}
printf("%d\n",ans);
return ;
}

问题D: 3897: Out of Sorts

问题E: 3898: Milking Order

本题要求最大化pos满足前面若干条边连起来是一个无环图。

求最优遍历顺序,想到拓扑排序check+二分答案,然后手打堆优化STL常数。

先存输入,每一次二分答案位置pos,把前面pos个连边系统前面连到后面,然后跑拓扑,每次选择入度为0,标号最小的一个遍历

这里用到heap了,然后使用priority_queue在不开O2情况下TLE,然后就写了一个手写堆。

# include <bits/stdc++.h>
using namespace std;
const int N=1e5+,M=2e5+;
int head[N],ind[N],ans[N];
bool vis[N];
vector<int>ipt[N];
int n,m,tot;
struct rec{int pre,to;}a[M];
inline int read()
{
int X=,w=; char c=;
while(c<''||c>'') {w|=c=='-';c=getchar();}
while(c>=''&&c<='') X=(X<<)+(X<<)+(c^),c=getchar();
return w?-X:X;
}
inline void write(int x)
{
if (x>) write(x/);
putchar(''+x%);
}
void adde(int u,int v)
{
ind[v]++;
a[++tot].pre=head[u];
a[tot].to=v;
head[u]=tot;
}
struct heap{
# define lson (x<<)
# define rson ((x<<)+)
# define fath (x>>)
int Size,c[N<<];
heap(){Size=;}
void down(int x) {
while (x<Size) {
if (lson>Size) break;
int t=lson;
if (rson<=Size&&c[rson]<c[lson]) t=rson;
if (c[x]<=c[t]) break;
swap(c[x],c[t]);
x=t;
}
}
void up(int x) {
while (x) {
if (c[x]>c[fath]) break;
swap(c[x],c[fath]);
x=fath;
}
}
int top(){return c[];}
void push(int x){c[++Size]=x;up(Size);}
void pop() {swap(c[],c[Size--]);down();}
bool empty(){ return !Size;}
}q;
bool check(int Mid)
{
tot=;
memset(vis,false,sizeof(vis));
memset(head,,sizeof(head));
memset(ind,,sizeof(ind));
for (int i=;i<=Mid;i++)
for (int j=;j<ipt[i].size();j++)
adde(ipt[i][j-],ipt[i][j]);
for (int i=;i<=n;i++)
if (ind[i]==) q.push(i);
ans[]=;
while (!q.empty()) {
int u=q.top(); q.pop();
vis[u]=true;
ans[++ans[]]=u;
for (int i=head[u];i;i=a[i].pre){
int v=a[i].to;
if (ind[v]==) return false;
ind[v]--;
if (ind[v]==) q.push(v);
}
}
for (int i=;i<=n;i++)
if (!vis[i]) return false;
return true;
}
int main()
{
n=read();m=read();
for (int i=;i<=m;i++) {
int r=read();
for (int j=;j<=r;j++) {
int t=read();
ipt[i].push_back(t);
}
}
int L=,R=m,Ans=;
while (L<=R) {
int mid=(L+R)>>;
if (check(mid)) Ans=mid,L=mid+;
else R=mid-;
}
if (Ans==) {
for (int i=;i<=n;i++) write(i),putchar(' ');
putchar('\n');
return ;
}
check(Ans);
for (int i=;i<=n;i++) write(ans[i]),putchar(' ');
putchar('\n');
return ;
}

问题E: 3898: Milking Order

问题F: 3899: Talent Show

考虑01分数规划,即二分答案套dp检查。

设答案$x\leq \frac{\sum w_i}{\sum t_i} $移项可得$\sum t_i - x \sum w_i \geq 0$

即要求我们对于给定参数x,求一组$w_i$和$t_i$满足$\sum t_i - x \sum w_i \geq 0$

即$max\{ \sum t_i - x \sum w_i \} \geq 0$

对于第i头奶牛的贡献就变成一个确定的数了,即$t_i-xw_i$

考虑01背包。

设f[x]表示当前选择总重量为x,$\sum t_i - x \sum w_i $的最大值。

考虑从x转移出去对x+w[i]有影响,有转移方程$f[x+w[i]]=max(f[x+w[i]],f[x]+t_i-xw_i)$

然后要求总重量超过W,事实上我们并不关心到底超过W多少,只要超过就行,那么就统计在恰好的地方

即统计在f[W]处,那么f[W]就是答案。

# include <bits/stdc++.h>
# define inf (<<)
using namespace std;
const int N=1e5+;
double f[N];
int w[N],t[N];
int n,W;
bool check(double x)
{
f[]=;
for(int i=;i<=W;i++) f[i]=-inf;
for (int i=;i<=n;i++)
for (int j=W;j>=;j--)
f[min(j+w[i],W)]=max(f[min(j+w[i],W)],f[j]+t[i]-x*w[i]);
return f[W]>=0.0;
}
int main()
{
scanf("%d%d",&n,&W);
for (int i=;i<=n;i++)
scanf("%d%d",&w[i],&t[i]);
double l=,r=inf,ans;
while (r-l>=(1e-)){
double mid=(l+r)/2.0;
if (check(mid)) ans=mid,l=mid;
else r=mid;
}
ans=ans*;
printf("%d\n",(int)ans);
return ;
}

问题F: 3899: Talent Show

问题G: 3900: Out of Sorts

我们不妨宏观考虑这个排序的问题,在对于A进行子冒泡排序的时候,可以发现,比第i个元素小的元素且在i右边的元素是以1贡献/次向i移动的。

所以第i个元素和第i+1元素之间的隔板产生的区间长度就是$ (maxpos-i+1-1)=maxpos-i $,其中$ maxpos $指的是排序以后比$a_i$元素更小的,但排在$a_i$元素的右边,且距离$a_i$最远的数$a_j$的下标(位置)$j$。

对于i被计算1次当他的前面隔板不是连续的,或者 后面隔板不是连续的满足其一即可,所以若把i存在于的这个隔板不连续的区间排成有序,那么仅对于元素i它被算的次数(产生的贡献)是$max(t_{i-1},t_i)$

说明一下: 如果i前后隔板都不连续的话i被产生$max(t_{i-1},t_i)$后便不产生贡献了,如果前面或后面隔板不连续显然。

有了上面的说明,这个题目的算法呼之欲出,

1. 遍历原数组,当前位置为i,求出$ t_i $,查找最后一个比$a_i$小的数出现的位置为j,令$ t_i = j - i $

2. 求出 $ans = \sum\limits_{i=1} ^ {n} \max \{ t_{i-1}, t_i \}$ 并输出。

显然按照上面模拟是$ O(n^2) $算法。

我们可以这样做,先把$a_i$每个元素记录它的值$val$和下标$i$,排序。

那么求一个前缀$ maxpos=max{a[i].id , maxpos }$,显然遍历到i位置的时候,前面都是比$ a[i] $ 的值,然后前面最大的$ id $号码就是$ maxpos $。

那么时间复杂度就降到$ O(nlog_2n) $

# include <bits/stdc++.h>
# define int long long
using namespace std;
const int N=1e5+;
struct rec{ int val,id; }a[N];
int n,t[N];
bool cmp(rec a,rec b)
{
if (a.val!=b.val) return a.val<b.val;
else return a.id<b.id;
}
signed main()
{
scanf("%lld",&n);
for (int i=;i<=n;i++)
scanf("%lld",&a[i].val),a[i].id=i;
sort(a+,a++n,cmp);
int maxpos=;
for (int i=;i<=n;i++) {
maxpos=max(maxpos,a[i].id);
t[i]=max(1ll,maxpos-i);
}
int ans=;
for (int i=;i<=n;i++)
ans+=max(t[i],t[i-]);
cout<<ans;
return ;
}

问题G: 3900: Out of Sorts

问题I: 3902: Disruption

这个题目非常有价值,我想专门开一个blog讲一讲这个题。

https://www.cnblogs.com/ljc20020730/p/10467324.html

欢迎支持!!!

【杂题1】USACO 2018 Open Contest-练习的更多相关文章

  1. [USACO 2018 December Contest]作业总结

    t1 Convention 题目大意 每一头牛都有一个来的时间,一共有\(n\)辆车,求出等待时间最长的那头牛等待的最小时间. 解法 第一眼看到这道题还以为是\(2018noip\)普及组的t3魔鬼题 ...

  2. [USACO 2018 Open Contest]作业总结

    t1-Out of Sorts 题目大意 将最大的数冒泡排序到最后需要多少次操作. 分析 排序后判断距离. ac代码 #include<bits/stdc++.h> #define N 1 ...

  3. 【二分+拓扑排序】Milking Order @USACO 2018 US Open Contest, Gold/upc_exam_6348

    目录 Milking Order @USACO 2018 US Open Contest, Gold/upc_exam_6348 PROBLEM 题目描述 输入 输出 样例输入 样例输出 提示 MEA ...

  4. 【USACO 2019 Feburary Contest】Gold

    模拟二月金组,三个半小时AK. USACO 2019 Feburary Contest, Gold T1 题意:给定一棵树,每个点有点权,每次可以进行以下操作之一: 更改一个点的点权 求某条路径上的点 ...

  5. [USACO 2018 Feb Gold] Tutorial

    Link: USACO 2018 Feb Gold 传送门 A: $dp[i][j][k]$表示前$i$个中有$j$个0且末位为$k$的最优解 状态数$O(n^3)$ #include <bit ...

  6. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  7. COCI 2018/2019 CONTEST #2 T4 Maja T5Sunčanje Solution

    COCI 2018/2019 CONTEST #2 T4 T5 Solution abstract 花式暴力 #2 T5 Sunčanje 题意 按顺序给你1e5个长方形(左下角坐标&& ...

  8. [USACO 2018 Jan Gold] Tutorial

    Link: USACO 2018 Jan Gold 传送门 A: 对于不同的$k$,发现限制就是小于$k$的边不能走 那么此时的答案就是由大于等于$k$的边形成的图中$v$所在的连通块除去$v$的大小 ...

  9. 正睿OI DAY3 杂题选讲

    正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n ...

  10. dp杂题(根据个人进度选更)

    ----19.7.30 今天又开了一个新专题,dp杂题,我依旧按照之前一样,这一个专题更在一起,根据个人进度选更题目; dp就是动态规划,本人认为,动态规划的核心就是dp状态的设立以及dp转移方程的推 ...

随机推荐

  1. BootStrap学习(7)_轮播图

    一.轮播图 Bootstrap 轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式.除此之外,内容也是足够灵活的,可以是图像.内嵌框架.视频或者其他您想要放置的任何类型的内容. 如果 ...

  2. Jquery UI 中的datepicker() ,获取日期后的回调函数onClose()

    <head> //引入相关的css/js <link rel="stylesheet" href="//code.jquery.com/ui/1.10. ...

  3. Luogu P1494 [国家集训队]小Z的袜子

    比较简单的莫队题,主要是为了熟练板子. 先考虑固定区间时我们怎么计算,假设区间\([l,r]\)内颜色为\(i\)的袜子有\(cnt_i\)只,那么对于颜色\(i\)来说,凑齐一双的情况个数为: \( ...

  4. [Oralce][InMemory]如何确定一个表已经被Populate 到In Memory 中?

    [Oralce][InMemory]如何确定一个表已经被Populate 到In Memory 中? 以如下方法来查看 POPULATE_STATUS 是不行的. SQL> select ins ...

  5. QT 小总结

    遇到的问题: 1:在debug模式下可以顺利执行,但是换到release模式下没法执行了.会显示 exited with code 1 . 解决办法:把产生的release文件放到QT的bin库下,看 ...

  6. 五年.net程序员Java学习之路

    大学毕业后笔者进入一家外企,做企业CRM系统开发,那时候开发效率最高的高级程序语言,毫无疑问是C#.恰逢公司也在扩张,招聘了不少.net程序员,笔者作为应届生,也乐呵呵的加入到.net程序员行列中. ...

  7. Jq_DOM元素方法跟JQuery 核心函数跟JQuery 事件方法

    JQuery DOM 元素 函数                            描述 .get()                           从队列中删除所有未运行的项目. .ind ...

  8. Python-注册登陆-20

    username = input('请输入你要注册的用户名:') password = input('请输入你要注册的密码:') with open('list_of_info',mode='w',e ...

  9. maven依赖的描述

    maven的坐标和依赖 坐标和依赖,主要涉及的就是pom文件的头部和<dependencies>标签部分(1)pom文件的头部 这里头部不是指pom文件的开头<project> ...

  10. 小学四则运算APP 第二阶段冲刺-第三天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第二次冲刺阶段时间:11.29~12.09 本次发布的是判断题的部分代码 panduanset.java import com.examp ...