T1.题目大意:n个人站成一排,有m个团队,每个人有且属于一个团队,可以让若干个人出队,任意交换这些人的位置后再站回去,问要让所有同一团队的人连续地站在一起,至少要出队几个。(n<=10^5,m<=20)

思路:求至少出队多少个等同于求至多有几个人可以不改变位置。假设我们确定了最后每个团队前面都站了哪些团队,显然每一队所在的区间都是确定的,考虑状压DP,f[i]表示状态为i(状态中表示已经加入了哪些团队)时最小出队人数,枚举一个团队j加入状态,对每个团队做前缀和即可知道该团队在一个区间里有多少人,即可转移,时间复杂度O(n*m+m*2^m)。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MM 20
#define MN 100000
int b[MN+],a[MM+],s[MM+][MN+],f[<<MM],p[<<MM];
int main()
{
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=;i<=n;++i)scanf("%d",&b[i]),++a[b[i]],s[b[i]][i]=;
for(i=;i<=m;++i)for(j=;j<=n;++j)s[i][j]+=s[i][j-];
memset(f,,sizeof(f));f[]=;
for(i=;i<<<m;++i)
{
for(j=;j<=m;++j)if(~i&(<<j-))
f[i|(<<j-)]=min(f[i|(<<j-)],f[i]+a[j]-s[j][p[i]+a[j]]+s[j][p[i]]),
p[i|(<<j-)]=p[i]+a[j];
}
printf("%d",f[(<<m)-]);
}

T2.题目大意:n个车站编号1~n,有三种车,慢车,特急车,快车,慢车走一站要时间a,特急要b,快车要c,慢车可以在任意站停,特急车只能在给定的m个车站停,现在要定k个快车站,其中必须覆盖所有特急车站,快车只能在快车站停,问从1号站出发,至多有几个站能在t时间内到达(下车、转车耗时0)。(n<=10^9,m<=k<=3000,b<c<a)

思路:先计算出不设快车站(或者说先设m个快车站覆盖特急车站)时能到达哪些站,显然要到这些站是先做特急车然后再坐一段慢车,于是我们可以算出从每个特急站下车坐慢车能到的最远的站(但要在下一个特急站之前,为了不重复统计),现在如果要新建一个快车站,自然我们应该建在某个从特急站下车后坐慢车能到的最远的站的下一个站,这样我们从特急站下车后就能直接搭上快车坐到这个站再坐慢车,我们先对每个候选的站都先算出建了这个站后能新到多少站,扔到堆里,每次我们取出最大的建,建了这个站后我们得到一种新的选择,就是在这个快车站下车后坐慢车能到的站的后一个站再建一个快车站,我们重新算一遍再扔回堆里即可。总复杂度O(klogk),实际上不用堆打个暴力找最大也能过嘛。

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define MN 3000
#define mp(x,y) make_pair(x,y)
int a,b,c,s[MN+],r[MN+];ll t;
priority_queue<pair<int,int> > pq;
void push(int x)
{
ll v=t-(ll)s[x]*b-(ll)(r[x]-s[x])*c;
if(v<){pq.push(mp(,x));return;}
int cp=r[x];
r[x]=min(r[x]+v/a+,(ll)s[x+]);
pq.push(mp(r[x]-cp,x));
}
int main()
{
int n,m,k,i,ans=;
scanf("%d%d%d%d%d%d%lld",&n,&m,&k,&a,&b,&c,&t);
for(i=;i<=m;++i)scanf("%d",&s[i]),--s[i];s[i]=n;
for(i=;i<=m;++i)
{
if((ll)s[i]*b>t)break;
r[i]=min(s[i]+(t-(ll)s[i]*b)/a+,(ll)s[i+]);
ans+=r[i]-s[i];
push(i);
}
for(i=k-m;i--;)
{
ans+=pq.top().first;
push(pq.top().second);
pq.pop();
}
printf("%d",ans-);
}

T3.没有这题

T4.题目大意:某派对搞了两个n个团队的人气排行榜,排行榜上有两个值,分别为排名第几的团队的所属学校和人气值,但第二个榜的报道出了点偏差,有几个学校写错了,有两个条件:一个团队的学校不会改变;由于第二个榜在第一个榜之后出,同一团队在第二个榜的人气不会低于在第一个榜的人气。现在问至少改几个第二个榜的学校才能让信息合法。(n<=200,000)

思路:我们让第一个榜和第二个榜的团队一一对应来建立二分图匹配模型,第一个榜的一个排名和第二个榜的一个排名能匹配当且仅当第二个榜的这个排名的人气不小于第一个榜的人气,且若这两个排名的学校相同,花费为0,否则花费为1,然后我们就能建出一个边数为O(n^2)的费用流图,大概能拿30分。把这个图优化到O(n)就能拿70分,优化思路是这样的:把第二个榜的每个点拆成两个点,分别表示与相同学校的匹配和任意学校匹配,然后再建一个点限制这两个点的流量,之后第一个榜的每个点分别向能匹配到的最小的任意学校点连费用1,向能匹配到的最小的相同学校连费用0,第二个榜的所有点再从小往大连流量INF费用0,图就建完了。但我们显然还是过不了200,000。其实这个匹配过程不用建图优化,是可以直接贪心解决的,每次找到最小的第二个榜的点向前匹配,如果我们找到了与它相同学校的点,显然直接匹配最优(因为此时不大于它的所有点向后能连的边是相同的),如果没有找到,我们只好选一个不同学校的匹配,但我们一时无法抉择选出哪个,就先记下在这之后要为它留下一个点匹配,我们用线段树维护每个未能直接匹配到的第二个榜的点,不大于它的点至多还能取几个,每次要找匹配点时,找到最大的不大于它的第一个榜的点,计算区间最小值看看会不会与前面冲突,不冲突就匹配并区间-1。总复杂度O(nlogn)。

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 200000
#define INF 0x7FFFFFFF
#define L (k<<1)
#define R (k<<1|1)
struct team{int t,p,x;}p[MN*+];
bool cmp(team a,team b){return a.p==b.p?a.x>b.x:a.p<b.p;}
vector<int> q[MN+];
struct node{int l,r,mn,mk;}t[MN*+];
int b[MN+],bn;
inline void up(int k){t[k].mn=min(t[L].mn,t[R].mn);}
inline void mark(int k,int x){t[k].mn+=x;t[k].mk+=x;}
inline void down(int k){t[k].mk?(mark(L,t[k].mk),mark(R,t[k].mk),t[k].mk=):;}
void build(int k,int l,int r)
{
t[k].mn=INF;
if((t[k].l=l)==(t[k].r=r))return;
int mid=l+r>>;
build(L,l,mid);build(R,mid+,r);
}
int query(int k,int l,int r)
{
if(t[k].l==l&&t[k].r==r)return t[k].mn;
down(k);
int mid=t[k].l+t[k].r>>;
if(r<=mid)return query(L,l,r);
if(l>mid)return query(R,l,r);
return min(query(L,l,mid),query(R,mid+,r));
}
void change(int k,int x,int z)
{
if(t[k].l==t[k].r){t[k].mn=z;return;}
down(k);
change(x>t[k].l+t[k].r>>?R:L,x,z);
up(k);
}
void dec(int k,int l,int r)
{
if(t[k].l==l&&t[k].r==r){mark(k,-);return;}
down(k);
int mid=t[k].l+t[k].r>>;
if(r<=mid)dec(L,l,r);
else if(l>mid)dec(R,l,r);
else dec(L,l,mid),dec(R,mid+,r);
up(k);
}
int main()
{
int n=read(),i,s=,x,ans=;
for(i=;i<n;++i)p[i].t=read(),p[i].p=read(),p[i].x=;
for(i=;i<n;++i)p[i+n].t=read(),p[i+n].p=read();
build(,,n);n<<=;sort(p,p+n,cmp);
for(i=;i<n;++i)
if(p[i].x)q[p[i].t].push_back(p[i].p),++s;
else
if(!q[p[i].t].empty())
{
x=lower_bound(b+,b+bn+,q[p[i].t][q[p[i].t].size()-])-b;
if(x>bn||query(,x,bn))q[p[i].t].pop_back(),--s,x<=bn?(dec(,x,bn),):;
else b[++bn]=p[i].p,change(,bn,s-bn),++ans;
}
else b[++bn]=p[i].p,change(,bn,s-bn),++ans;
printf("%d",ans);
}

洛谷4月月赛R1的更多相关文章

  1. 洛谷3月月赛 R1 Step! ZERO to ONE

    洛谷3月月赛 R1 Step! ZERO to ONE 普及组难度 290.25/310滚粗 t1 10分的日语翻译题....太难了不会... t2 真·普及组.略 注意长为1的情况 #include ...

  2. 洛谷4月月赛R1 Happy Poppin' Party Train

    来自FallDream的博客,未经允许,请勿转载,谢谢. 听学长说的就来玩一玩,随便乱打打  没想到一堆人被取消了成绩,莫名混了个Rank3 还有第一题数据肯定是有问题 --------------- ...

  3. 洛谷4月月赛R2

    洛谷4月月赛R2 打酱油... A.koishi的数学题  线性筛约数和就可以\(O(N)\)了... #include <iostream> #include <cstdio> ...

  4. 【洛谷5月月赛】玩游戏(NTT,生成函数)

    [洛谷5月月赛]玩游戏(NTT,生成函数) 题面 Luogu 题解 看一下要求的是什么东西 \((a_x+b_y)^i\)的期望.期望显然是所有答案和的平均数. 所以求出所有的答案就在乘一个逆元就好了 ...

  5. 【LGR-054】洛谷10月月赛II

    [LGR-054]洛谷10月月赛II luogu 成功咕掉Codeforces Round #517的后果就是,我\(\mbox{T4}\)依旧没有写出来.\(\mbox{GG}\) . 浏览器 \( ...

  6. 【LGR-051】洛谷9月月赛

    [LGR-051]洛谷9月月赛 luogu 签到题 description 给出\(K\)和质数\(m\),求最小的\(N\)使得\(111....1\)(\(N\)个\(1\))\(\equiv k ...

  7. 「LGR-049」洛谷7月月赛 D.Beautiful Pair

    「LGR-049」洛谷7月月赛 D.Beautiful Pair 题目大意 : 给出长度为 \(n\) 的序列,求满足 \(i \leq j\) 且 $a_i \times a_j \leq \max ...

  8. 洛谷9月月赛round2

    洛谷9月月赛2 t1 题意:懒得说了 分析:模拟 代码: program flag; var a:..,..]of char; n,i,m,j,x,y,ans,k:longint; begin ass ...

  9. 「P4996」「洛谷11月月赛」 咕咕咕(数论

    题目描述 小 F 是一个能鸽善鹉的同学,他经常把事情拖到最后一天才去做,导致他的某些日子总是非常匆忙. 比如,时间回溯到了 2018 年 11 月 3 日.小 F 望着自己的任务清单: 看 iG 夺冠 ...

随机推荐

  1. 《高级软件测试》Linux平台Jira的安装与配置

    现在大部分的程序开发都是在linux下进行的,jira更多的时候是安装在linux上,那么,如何在linux下安装配置jira呢?本文将以Ubuntu 17.10和jira7.5.2为例,对linux ...

  2. nyoj 韩信点兵

    描述相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排.五人一排.七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了.输入3个非负整数a,b,c ,表示每种队形排尾的人数 ...

  3. JAVA_SE基础——3.Java程序的开发流程

    上一篇,写的是JAVA的环境变量的配置,今天我抽空写篇Java程序的开发流程,下面的教程是我结合书本和毕向东老师的视频写下的心的~ 在没有真正写Java程序前,首先需要了解Java程序的开发过程. S ...

  4. 帧动画的创建方式 - 纯Java代码方式

    废话不多说,先看东西 帧动画的创建方式主要以下2种: * 用xml创建动画: * 纯Java代码创建动画:   本文内容主要关注 纯java代码创建帧动画 的方式: 用xml创建帧动画:http:// ...

  5. Django之Model进阶的更多操作

    Django之Model进阶的更多操作   一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) ...

  6. python网络爬虫与信息提取 学习笔记day2

    Day2: 查看robots协议: 查看京东的robots协议 查看百度的robots协议,可以看到百度拒绝了搜狗的爬虫233 爬取京东商品页面相关信息: import requests url = ...

  7. 前端之BOM和DOM

    BOM和DOM简介 BOM(Browser Object Model)是指浏览器对象模型,它使JavaScript有能力与浏览器进行“对话”. DOM(Document Object Model)是指 ...

  8. AOP及专有名词通俗解答

    AOP面向切面编程,是一种编程思想,并不是Spring专有,Spring是封装代理模式完成,之前的博客中也写到了关于AOP的文章,Filter和代理,请见<以此之长,补彼之短----AOP(Fi ...

  9. Python基础--函数的嵌套和闭包

    一.名称空间和作用域 名称空间:Python所有有关命名的操作都是在操作名称空间,例如变量名,函数名 1.内置名称空间:Python解释器提供好的功能,解释器启动跟着一起启动,是全局作用域 2.全局名 ...

  10. Python系列-python内置函数

    abs(x) 返回数字的绝对值,参数可以是整数.也可以是浮点数.如果是复数,则返回它的大小 all(iterable) 对参数中的所有元素进行迭代,如果所有的元素都是True,则返回True,函数等价 ...