匹配

给出一个\(n(n\leq80)\)个点对\(n\)个点的带权二分图,求所有最大权匹配的交集。

先求出一个最大权匹配,然后枚举每一条匹配中的边,检验删除该边后是否还能形成最大权匹配。如果能则说明该边不在交集中,否则一定在交集中。

电源插排

一个长度为\(n(n\leq10^9)\)的插排,初始时是空的。进行\(Q(Q\leq10^5)\)次操作,操作有三种:

  • 向整个插排上最大的空区间(相等取最右)的中间(也取右)插上一个插头\(x\)。
  • 询问区间\([L,R]\)中有几个插头。
  • 拔出插头\(x\)。

用动态开点线段树来做即可。每条线段维护四个值:左起最长空区间的右端点,区间最长空区间的左、右端点,右起最长空区间的左端点。再记录一下插头\(x\)的位置就可以删除啦。

拼图

给出\(n(n\leq16)\)块四连通碎片,求有多少种方案将他们一起拼成一个\(4\times4\)的正方形。若没有,输出No Solution;只有一种,输出Yes, only one!和这个方案;否则输出Yes, many!

似乎直接爆搜即可,优化一点可以按块由大到小搜索,再优化可以搞搞状压什么的。

上升子序列

给出一个\(n(n\leq10^5)\)长度的数列,求该数列有多少个不同的长度至少为\(2\)的上升子序列,答案对\(10^9+7\)取模。两个子序列\(a,b\)被认为不同当且仅当\(\exists i,a_i \neq b_i\)。

记录\(cnt[i]\)表示目前以数字\(i\)为结尾的不同上升子序列有多少个。当做到\(a_i\)时,\(cnt[a_i]\)变为\(1+\sum_{i=1}^{a[i]-1}cnt[i]\)个,额外的\(1\)表示只有一个数的序列\(\{a_i\}\),求和表示\(a_i\)能够接在多少个上升子序列后。要注意\(cnt[a_i]\)是变为,而不是加上,因为如果存在\(a_{i'}=a_i(i'<i)\),那么以\(a_{i'}\)结尾的上升子序列一定出现在以\(a_i\)结尾的上升子序列中(把原序列中的\(a_{i'}\)换成\(a_i\))。

那么我们需要支持单点修改和前缀求和,可以用树状数组解决。

Alice and Bob

对于序列\(\{x_n\}(n\leq10^5)\),记\(a_i\)表示以\(x_i\)结尾的最长上升子序列长度,\(b_i\)表示以\(x_i\)开头的最长下降子序列长度。给出\({a_n}\),求\(\sum_{i=1}^nb_i\)的最大值。

若在\(a_1..a_{i-1}\)中有\(k\)个大于\(a_i\),那么说明在\(x_1..x_{i-1}\)中,至少有\(k\)个大于\(x_i\),至少有\(a_i-1\)个小于\(x_i\)。

我没太看懂的题解:现在我们已知了一些大小关系。对于未知的关系,我们默认左边大于右边。构造序列并求\(\sum_{i=1}^nb_i\)即可。

电影评分

搞一个电影评分系统,进行\(n(n\leq10^4)\)次操作,操作有三种:

  • 发布一部编号为\(ID\)的电影,有\(x(x\leq5)\)个主演\(\{actor_x\}\),其评分为与其有共同主演的最新电影的评分,若没有则为\(0\)。
  • 查询排名为\(x\)的电影的编号。排名以评分为第一关键字,发布时间为第二关键字。
  • 将电影\(ID\)的评分调整为原评分与\(x\)的平均数。

题解:将题目中的分数分为整数部分和小数部分,将小数部分写成二进制形式,此时可以使用后缀平衡树维护小数之间的大小关系。将小数部分和整数部分结合即可比较分数的大小关系。没大看懂,也不会后缀平衡树。

Code

//匹配
#include <cstdio>
#include <cstring>
#include <queue>
int const N=300;
int const INF=0x3F3F3F3F;
int min(int x,int y) {return x<y?x:y;}
int n;
int h[N],cnt;
struct edge{int u,v,c,w,nxt;} ed[N*N];
void edAdd(int u,int v,int c,int w)
{
cnt++; ed[cnt].u=u,ed[cnt].v=v,ed[cnt].c=c,ed[cnt].w=w,ed[cnt].nxt=h[u],h[u]=cnt;
cnt++; ed[cnt].u=v,ed[cnt].v=u,ed[cnt].c=0,ed[cnt].w=-w,ed[cnt].nxt=h[v],h[v]=cnt;
}
int s,t;
int dst[N],path[N];
std::queue<int> Q; bool inQ[N];
void clear() {for(int i=2;i<=cnt;i++) ed[i].c=i&1?0:ed[i].c+ed[i^1].c;}
bool SPFA()
{
for(int u=s;u<=t;u++) dst[u]=-INF,path[u]=0;
memset(inQ,false,sizeof inQ);
dst[s]=0; Q.push(s),inQ[s]=true;
while(!Q.empty())
{
int u=Q.front(); Q.pop(),inQ[u]=false;
for(int i=h[u];i;i=ed[i].nxt)
{
int v=ed[i].v,w=ed[i].w;
if(ed[i].c&&dst[u]+w>dst[v])
{
dst[v]=dst[u]+w,path[v]=i;
if(!inQ[v]) Q.push(v),inQ[v]=true;
}
}
}
return dst[t]>-INF;
}
int maxFl()
{
int cost=0;
while(SPFA())
{
int fl=INF;
for(int i=path[t];i;i=path[ed[i^1].v]) fl=min(fl,ed[i].c);
for(int i=path[t];i;i=path[ed[i^1].v]) ed[i].c-=fl,ed[i^1].c+=fl;
cost+=fl*dst[t];
}
return cost;
}
int cntM,M[N];
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
scanf("%d",&n);
s=0,t=n+n+1; cnt=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) {int x; scanf("%d",&x); edAdd(i,n+j,1,x);}
for(int i=1;i<=n;i++) edAdd(s,i,1,0),edAdd(n+i,t,1,0);
int ans=maxFl(); printf("%d\n",ans);
cntM=0;
for(int u=1;u<=n;u++)
for(int i=h[u];i;i=ed[i].nxt) if(!ed[i].c&&ed[i].v!=s) M[++cntM]=i;
for(int k=1;k<=cntM;k++)
{
clear(),ed[M[k]].c=0;
int cost=maxFl();
ed[M[k]].c=1;
if(cost<ans) printf("%d %d\n",ed[M[k]].u,ed[M[k]].v-n);
}
return 0;
}
//电源插排
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
inline char gc()
{
static char now[1<<16],*S,*T;
if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
return *S++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
int const Q=1e5+10;
int n,q; map<int,int> pos;
#define s sg[s0]
int rt,sgCnt;
struct seg{int eptL0,eptR0,eptL,eptR,sum; int Lc,Rc;} sg[40*Q];
void create(int s0,int L0,int R0) {s.eptL0=s.eptR=R0,s.eptR0=s.eptL=L0,s.sum=0;}
void update(int s0,int L0,int R0)
{
int mid=L0+R0>>1; seg Ls=sg[s.Lc],Rs=sg[s.Rc];
s.eptL0=Ls.eptL0; if(Ls.eptL0==mid) s.eptL0=Rs.eptL0;
s.eptR0=Rs.eptR0; if(Rs.eptR0==mid+1) s.eptR0=Ls.eptR0;
int len1=Ls.eptR-Ls.eptL+1,len2=Rs.eptL0-Ls.eptR0+1,len3=Rs.eptR-Rs.eptL+1;
int mx=max(len2,max(len1,len3));
if(len3==mx) s.eptL=Rs.eptL,s.eptR=Rs.eptR;
else if(len2==mx) s.eptL=Ls.eptR0,s.eptR=Rs.eptL0;
else if(len1==mx) s.eptL=Ls.eptL,s.eptR=Ls.eptR;
s.sum=Ls.sum+Rs.sum;
}
int L,R;
void add(int s0,int L0,int R0,int v)
{
if(L<=L0&&R0<=R)
{
s.sum=v;
if(v==1) s.eptL0=L0-1,s.eptR0=R0+1,s.eptL=L0+1,s.eptR=L0;
else s.eptL0=s.eptR0=s.eptL=s.eptR=L0;
return;
}
int mid=L0+R0>>1;
if(!s.Lc) create(s.Lc=++sgCnt,L0,mid);
if(!s.Rc) create(s.Rc=++sgCnt,mid+1,R0);
if(L<=mid) add(s.Lc,L0,mid,v); if(mid<R) add(s.Rc,mid+1,R0,v);
update(s0,L0,R0);
}
int query(int s0,int L0,int R0)
{
if(s0==0) return 0;
if(L<=L0&&R0<=R) return s.sum;
int mid=L0+R0>>1; int res=0;
if(L<=mid) res+=query(s.Lc,L0,mid);
if(mid<R) res+=query(s.Rc,mid+1,R0);
return res;
}
int main()
{
freopen("switch.in","r",stdin);
freopen("switch.out","w",stdout);
n=read(),q=read();
create(rt=++sgCnt,1,n);
for(int i=1;i<=q;i++)
{
int k=read();
if(k==0) {L=read(),R=read(); printf("%d\n",query(rt,1,n));}
else
{
L=R=(sg[rt].eptL+sg[rt].eptR-1)/2+1;
if(pos[k]) L=R=pos[k],add(rt,1,n,0),pos[k]=0;
else add(rt,1,n,1),pos[k]=L;
}
}
return 0;
}
//上升子序列
#include <cstdio>
#include <algorithm>
using namespace std;
int const N=1e5+10;
int const H=1e9+7;
int n,a[N]; int n0,map[N];
int tr[N];
void add(int x,int v) {while(x<=n0) tr[x]=(tr[x]+v)%H,x+=x&(-x);}
int sum(int x) {int res=0; while(x) res=(res+tr[x])%H,x-=x&(-x); return res;}
int pre[N];
int main()
{
freopen("subsequence.in","r",stdin);
freopen("subsequence.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),map[i]=a[i];
sort(map+1,map+n+1); n0=unique(map+1,map+n+1)-(map+1);
for(int i=1;i<=n;i++) a[i]=lower_bound(map+1,map+n0+1,a[i])-map;
for(int i=1;i<=n0;i++) pre[i]=0;
for(int i=1;i<=n;i++)
{
int res=sum(a[i]-1)+1;
add(a[i],res-pre[a[i]]); pre[a[i]]=res;
}
printf("%d\n",sum(n0)-n0);
return 0;
}

TJOI2014的更多相关文章

  1. P3968 [TJOI2014]电源插排

    P3968 [TJOI2014]电源插排 线段树维护最长空区间及左端点位置,这个和$nlongn$的动态最大子序和差不多,就不多解释了 $n$较大哈希优化空间 My complete code: #i ...

  2. bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)

    5157: [Tjoi2014]上升子序列 题目:传送门 题解: 学一下nlogn的树状数组求最长上生子序列就ok(%爆大佬) 离散化之后,用一个数组记录一下,直接树状数组做 吐槽:妈耶...一开始不 ...

  3. [TJOI2014]拼图

    嘟嘟嘟 一眼看上去像状压dp,然后越想复杂度越不对劲,最后发现和爆搜差不多,索性就写爆搜了,复杂度\(O(\)能过\()\). 别忘了填拼图和回溯的时候只动拼图中是1的部分,不要把\(n * m\)的 ...

  4. [TJOI2014]Alice and Bob[拓扑排序+贪心]

    题意 给出一个序列的以每一项结尾的 \(LIS\) 的长度a[],求一个序列,使得以每一项为开头的最长下降子序列的长度之和最大. \(n\leq 10^5\) . 分析 最优解一定是一个排列,因为如果 ...

  5. [BZOJ 5155][Tjoi2014]电源插排

    传送门 网上大部分题解都写得是动态开点线段树,然而像\(MiEcoku\)这么懒惰的显然不会去写线段树... \(\color{green}{solution}\) 我们考虑来点骚操作. 线段树维护的 ...

  6. 【bzoj5157】[Tjoi2014]上升子序列 树状数组

    题目描述 求一个数列本质不同的至少含有两个元素的上升子序列数目模10^9+7的结果. 题解 树状数组 傻逼题,离散化后直接使用树状数组统计即可.由于要求本质不同,因此一个数要减去它前一次出现时的贡献( ...

  7. [BZOJ 5158][Tjoi2014]Alice and Bob

    传送门 \(\color{green}{solution}\) 贪心 /************************************************************** P ...

  8. 【[TJOI2014]上升子序列】

    这本质上是一个\(dp\) 如果没有"两个上升子序列相同,那么只需要计算一次"这一个性质,那么就很好做了,我们用\(dp[i]\)表示以\(i\)结尾的上升子序列个数,那么就有\( ...

  9. vijos1859[TJOI2014]电源插排

    题意:小 M 的实验室有很多电源插排.这些插排的编号从 1 到 N,由左向右排成一排.每天早晨,这些插排都是没有被使用的.每当一个学生来到实验室,他就将自己的笔记本电源插到某一个未被使用的插排上.实验 ...

  10. 【刷题】BZOJ 5154 [Tjoi2014]匹配

    Description 有N个单身的男孩和N个单身女孩,男孩i和女孩j在一起得到的幸福值为Hij.一个匹配即对这N个男孩女孩的安排: 每个男孩恰好有一个女朋友,每个女孩恰好有一个男朋友.一个匹配的幸福 ...

随机推荐

  1. JVM 内存机制理解【转自http://www.cnblogs.com/dingyingsi/p/3760447.html】

    我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存,用户缓冲用户IO等待导致CPU的等 ...

  2. Masonry自动布局与UIScrolView适配

    Masonry介绍 Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布局 简洁明了 并具有高可读性 而且同时支持 iOS 和 Max OS X.可以通过cocoa ...

  3. 作用域链、this细说

    一.作用域链 作用域:浏览器给js的一个生存环境(栈内存) 作用域链:js中的关键字var和function 都可以提前声明和定义,提前声明和定义的放在我们的内存地址(堆内存)中.然后js从上到下逐行 ...

  4. APM系列-国外新兴厂商New Relic vs. AppDynamics

    前: New Relic的上市使得IT和资本界开始重新重视APM,当然跟传统APM相比,New Relic还是有相当的创新,另外还有一点是目前的创业潮导致的企业级需求增大. In recent yea ...

  5. String.format()【示例详解】

    String.format()[示例详解] 整理者:Vashon 前言: String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.fo ...

  6. XCode调试器LLDB

    与调试器共舞 - LLDB 的华尔兹 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一 ...

  7. prevent to do sth 与 prevent sb (from) doing 用法

    prevent to do sth 如: Do not water in before making a turn every time 9 days, make wilting of its bra ...

  8. http以及http协议简单理解

    HTTP协议是超文本传输协议的缩写,是用于从万维网(WWW)服务器传输超文本到本地浏览器的传送协议:HTTP是一个基于TCP/IP通信协议来传递数据(HTML文件, 图片文件, 查询结果等)HTTP作 ...

  9. Oracle错误 1053: 该服务没有响应启动或控制请求

    在服务中,启动oracleDBConsolenewdb服务时,出现了 错误 1053: 该服务没有响应启动或控制请求 在网上查了以后你会发现这是一个非常宽泛的错误,然而我们的建议是去看传说中的orac ...

  10. Android(java)学习笔记170:服务(service)之服务的生命周期 与 两种启动服务的区别

    1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.Service 的两种启动方法和区别: (1)Servi ...