T1

从高到底按位确定答案

A=1时f[i]表示前i个数合法的划分至少需要分出几段,时间复杂度$O(n^2log(ans))$

A>1时f[i][j]表示前i个数划分为j段是否可能合法,转移显然,时间复杂度$O(n^3log(ans)/32)$

#include<cstdio>
#include<cstring>
#include<bitset>
typedef long long i64;
int n,A,B;
int f[];
i64 s[],ans=;
std::bitset<>d[];
int main(){
scanf("%d%d%d",&n,&A,&B);
for(int i=;i<=n;++i)scanf("%lld",s+i),s[i]+=s[i-];
if(A==){
for(int x=;x>=;--x){
i64 v=ans|((1ll<<x)-);
for(int i=;i<=n;++i){
f[i]=0x3f3f3f3f;
for(int j=;j<i;++j)if(((s[i]-s[j])|v)==v&&f[j]+<f[i])f[i]=f[j]+;
}
if(f[n]>B)ans|=1ll<<x;
}
}else{
d[][]=;
for(int x=;x>=;--x){
i64 v=ans|((1ll<<x)-);
for(int i=;i<=n;++i){
d[i].reset();
for(int j=;j<i;++j)if(((s[i]-s[j])|v)==v)
d[i]|=d[j]<<;
}
bool dd=;
for(int i=A;i<=B;++i)dd|=d[n][i];
if(!dd)ans|=1ll<<x;
}
}
printf("%lld\n",ans);
return ;
}

T2

对每个不同的(p[i],b[i]%p[i]),新建一些点表示这个i可以走到的位置,每个位置和每个i也建出对应的点

最后可以转为01边权最短路

可以证明时空复杂度均为$O(n^\frac 3 2)$

#include<bits/stdc++.h>
const int inf=0x3f3f3f3f,C=;
int n,m,b[],p[],B;
struct edge{
int to;
edge*nx;
}*ep=,*mep=;
edge*e0[*C];
int l[*C];
bool is[*C];
void ae(int a,int b){
if(ep==mep)ep=new edge[],mep=ep+;
*ep=(edge){b,e0[a]};
e0[a]=ep++;
}
int idp;
struct node{int w,l;void upd1(int);};
std::deque<node>q;
std::map<int,int>mp;
void node::upd1(int u){
if(::l[u]>l+)q.push_back((node){u,::l[u]=l+});
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<m;++i)scanf("%d%d",b+i,p+i);
idp=n+m;
for(int i=;i<m;++i){
ae(b[i],n+i);
ae(n+i,b[i]);
int x=p[i],y=b[i]%x;
int&z=mp[x<<|y];
if(!z){
z=idp;
int a;
for(a=y;a+x<n;a+=x){
is[idp]=;
ae(idp++,a);
}
ae(idp++,a);
}
ae(n+i,z+(b[i]-y)/x);
}
std::fill(l,l+idp+,inf);
q.push_back((node){n,l[n]=});
while(!q.empty()){
node w=q.front();q.pop_front();
if(w.l!=l[w.w])continue;
if(w.w==n+)return printf("%d\n",w.l),;
for(edge*i=e0[w.w];i;i=i->nx){
int u=i->to;
if(l[u]>w.l)q.push_front((node){u,l[u]=w.l});
}
if(is[w.w-])w.upd1(w.w-);
if(is[w.w])w.upd1(w.w+);
}
return puts("-1"),;
}

T3

对同侧的直接计算贡献,否则考虑不同侧的

K=1,中位数位置最优

K=2,可以证明按$S_i+T_i$排序后划分成左右两部分后按K=1的情况处理,能找到最优解

带插入的中位数可以用对顶堆维护

时间复杂度$O(nlogn)$

#include<bits/stdc++.h>
typedef long long i64;
int k,n;
char s1[],s2[];
int p1,p2,xs[],xp=;
i64 ans=;
int abs(int x){return x>?x:-x;}
struct pos{
int a,b;
bool operator<(pos w)const{return a+b<w.a+w.b;}
}ps[];
int pp=;
i64 ss1=,ss2=,f[];
std::priority_queue<int>q1;
std::priority_queue<int,std::vector<int>,std::greater<int> >q2;
void init(){
q1=std::priority_queue<int>();
q2=std::priority_queue<int,std::vector<int>,std::greater<int> >();
ss1=ss2=;
}
void ins(int x){
if(q1.size()&&x<=q1.top()){
q1.push(x),ss1+=x;
if(q1.size()>q2.size()+){
int x=q1.top();q1.pop();
ss1-=x;ss2+=x;
q2.push(x);
}
}else{
q2.push(x),ss2+=x;
if(q2.size()>q1.size()+){
int x=q2.top();q2.pop();
ss2-=x;ss1+=x;
q1.push(x);
}
}
}
void mins(i64&a,i64 b){if(a>b)a=b;}
i64 cal(){
return ss2-ss1;
}
int main(){
scanf("%d%d",&k,&n);
if(k==){
for(int t=;t<n;++t){
scanf("%s%d%s%d",s1,&p1,s2,&p2);
if(s1[]==s2[])ans+=abs(p2-p1);
else ++ans,xs[xp++]=p1,xs[xp++]=p2;
}
if(xp){
std::nth_element(xs,xs+xp/,xs+xp);
int x=xs[xp/];
for(int a=;a<xp;++a)ans+=abs(xs[a]-x);
}
}else{
for(int t=;t<n;++t){
scanf("%s%d%s%d",s1,&p1,s2,&p2);
if(s1[]==s2[])ans+=abs(p2-p1);
else ++ans,ps[pp++]=(pos){p1,p2};
}
std::sort(ps,ps+pp);
if(pp){
init();
for(int a=;a<pp;++a){
ins(ps[a].a);ins(ps[a].b);
f[a]=cal();
}
i64 mx=f[pp-];
init();
for(int a=pp-;a;--a){
ins(ps[a].a);ins(ps[a].b);
mins(mx,cal()+f[a-]);
}
ans+=mx;
}
}
printf("%lld\n",ans);
return ;
}

bzoj 4069~4071 APIO2015的更多相关文章

  1. bzoj 4069 [Apio2015]巴厘岛的雕塑 dp

    [Apio2015]巴厘岛的雕塑 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 494  Solved: 238[Submit][Status][Dis ...

  2. BZOJ 4069 [Apio2015]巴厘岛的雕塑 ——贪心

    自己首先想了一种方法$f(i)$表示前$i$个最小值为多少. 然而发现位运算并不满足局部最优性. 然后我们可以从高到低贪心的判断,使得每一组的和在一个特定的范围之内. 还要特判最后一个Subtask, ...

  3. bzoj 4071: [Apio2015]巴邻旁之桥【splay】

    用权值线段树会容易一些并快一些,但是想复健一下splay所以打了splay 然后果然不会打了. 解题思路: 首先把家和办公室在同一侧的提出来直接加进答案里: 对于k=1,直接选所有办公室和家的中位数即 ...

  4. bzoj 4069: [Apio2015]巴厘岛的雕塑【dp】

    居然要对不同的数据写不同的dp= = 首先记得开long long,<<的时候要写成1ll<<bt 根据or的性质,总体思路是从大到小枚举答案的每一位,看是否能为0. 首先对于 ...

  5. 4071: [Apio2015]巴邻旁之桥

    Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...

  6. 巴厘岛的雕塑 BZOJ 4069

    巴厘岛的雕塑 题解: 题意是要求分组使每组的和按位取或的值最小 那么考虑贪心,尽量使高位为0 于是枚举位置,从最高位枚举 假设当前枚举到第l位. 令 f[i][j] 表示前 i 个数分成 j 组,满足 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. bzoj千题计划239:bzoj4069: [Apio2015]巴厘岛的雕塑

    http://www.lydsy.com/JudgeOnline/problem.php?id=4069 a!=1: 从高位到低位一位一位的算 记录下哪些位必须为0 dp[i][j] 表示前i个数分为 ...

  9. [BZOJ 4071] 巴邻旁之桥

    Link: BZOJ 4071传送门 Solution: 首先算出能提前算的贡献 $K=1$:肯定选中间的点,小学数学 $K=2$:对于每对$(x,y)$一定选离$(x+y)/2$近的桥 也就是说将$ ...

随机推荐

  1. Lucene 基础知识

    1. 数据分类 结构化数据: 指具有固定格式或有限长度的数据,如数据库等; 非结构化数据: 指不定长或无固定格式的数据, 如邮件,word 文档等磁盘上的文件; 1.1 非结构化数据查询方法 顺序扫描 ...

  2. 使用dos2unix批量转换文件

    使用dos2unix批量转换文件 dos2unix是Linux下的一个用户转换格式的程序,由于windows上文件的结束符和linux上的不同,那么在windows上编写的文件或者是脚本在Linux上 ...

  3. vnc viewer 点击system 卡死现象

    转自:http://zhangjunli177.blog.163.com/blog/static/1386073082012103052527557/ VNC viewer desktop dead ...

  4. Andrew and Taxi CodeForces - 1100E (思维,拓扑)

    大意: 给定有向图, 每条边有一个权值, 假设你有$x$个控制器, 那么可以将所有权值不超过$x$的边翻转, 求最少的控制器数, 使得翻转后图无环 先二分转为判定问题. 每次check删除能动的边, ...

  5. HDU 4122 单调队列

    转载自:http://blog.csdn.net/lvshubao1314/article/details/46910271 DES :给出n个订单和m是商店的开放时间.然后n行给出n个订单的信息.然 ...

  6. Qt enum使用总结

    一.enum 自省 const QMetaObject &mo = [ClassName]::staticMetaObject; int index = mo.indexOfEnumerato ...

  7. 线程的同步之Synchronized在单例模式中的应用

    synchronized在单例模式中的使用 在单例模式中有一种懒汉式的单例,就是类初始化的时候不创建对象.等第一次获取的时候再创建对象.这种单例在单线程下是没有问题的获取的也都是同一个对象.但是如果放 ...

  8. Eclipse Oxygen SVN Connector Setup

    新版的Eclipse(Oxygen)安装完Subversive后,现时无法自动安装SVN Connector,无论选择哪个都会自动关闭. 解决方法: Help -> Install New So ...

  9. SpringInAction--SpringMvc高级技术(servlet、filter、multipart)

    前面学了spirng的一些配置,以及web方面的知识,今天就在学习一下在spring比较常用的一些高级技术... 首先来介绍下什么叫servlet吧(来着维基百科) Servlet(Server Ap ...

  10. adb命令安装apk

    1.将需要安装的apk放在platform-tools下 2.将手机和电脑连接,在cmd中输入 adb devices查看 3.使用adb命令安装apk,在cmd中输入:adb install apk ...