2017 济南综合班 Day 7
a

两个指针L、R
R开始指向恰好[R,n]有不超过k个逆序对的地方
随着L的右移,R指针只会右移
逆序对有2部分
1、L左侧与其他位置形成的逆序对
2、R右侧与其他位置形成的逆序对
用树状数组分别维护这两部分
同时维护当前逆序对个数
每次L右移,新的L会增加与L左侧的逆序对和与R右侧的逆序对
每次R右移,R的消失会减少R右侧的逆序对和与L左侧的逆序对
#include<cstdio>
#include<algorithm>
#define N 100012
using namespace std;
int tot;
int a[N],hash[N];
int c1[N],c2[N];
int query1(int x)
{
int sum=; while(x) { sum+=c1[x]; x-=x&-x; } return sum;
}
int query2(int x)
{
int sum=; while(x) { sum+=c2[x]; x-=x&-x; } return sum;
}
void add1(int x,int y)
{
while(x<=tot) { c1[x]+=y; x+=x&-x; }
}
void add2(int x,int y)
{
while(x<=tot) { c2[x]+=y; x+=x&-x; }
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int n,k;
long long ans=,cnt=;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",&a[i]),hash[i]=a[i];
sort(hash+,hash+n+);
tot=unique(hash+,hash+n+)-(hash+);
for(int i=;i<=n;i++) a[i]=lower_bound(hash+,hash+tot+,a[i])-hash;
int R=n;
while(R>=)
{
add2(a[R],);
cnt+=query2(a[R]-);
R--;
}
R++;
for(int L=;L<n;L++)
{
if(L==R)
{
cnt=cnt-(L--query1(a[R]))-query2(a[R]-);
add2(a[R++],-);
}
cnt=cnt+L--query1(a[L])+query2(a[L]-);
add1(a[L],);
while(cnt>k && R<=n )
{
cnt=cnt-(L-query1(a[R]))-query2(a[R]-);
add2(a[R++],-);
}
if(cnt<=k) ans+=n-R+;
}
printf("%I64d",ans);
}
b

状态压缩式的搜索
但一开始分明是按着DP做的
于是就写出了个又像DP又像bfs的代码
两个结论:
1、成功搞事的前提是 a中除1之外的数 都能由前面的2个数相加得到(可以是2个相同的数)
2、最优解b中的数一定可以是a中的某些数
先判断a是否符合结论1,同时记录a中的每个数可以由哪两个数相加得到
N只有23,将N状态压缩,每一位表示当前状态b中有没有a中的这个数
设state[i][] 表示当前第i次搞事,b中可以有的a的状态
那么state[i][]可以由state[i-1][]转移的条件是
若a[p]+a[q]=a[i] ,state[i-1][]这个状态含有任意一对p、q
所以枚举state[i-1][]中的每一种状态,若这个状态可以转移
不管选哪对p、q,总要用i替换掉这个状态中的某一个位置或者是新增一个位置
替换:设当前状态为j,要替换掉第k位,新的状态为 j^k|i
新增:j^i
最后枚举state[n][]中的每一种状态,1的个数取最少就是答案
优化1:滚动数组
优化2:状态判重,新开一个数组vis[],int类型,用时间戳的方式判重,避免每次清空
优化3:类似于可行性剪枝,再枚举i-1的状态时,加上
if(minans<当前状态已经用的a的数量) continue;
minans=min(minans,当前状态已经用的a的数量+最多还能用的a的数量);
#include<cstdio>
#include<algorithm>
#define N 23
using namespace std;
int dp[(<<N)+];
int n,num[N+];
int way[N+][][];
int state[][(<<N)+];
int vis[(<<N)+];
int sum[(<<N)+];
int count(int x)
{
int cnt=;
while(x) cnt+=x&,x>>=;
return cnt;
}
int main()
{
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
bool can=false;
for(int a=;a<=n;a++)
{
can=false;
for(int b=;b<a;b++)
for(int c=b;c<a;c++)
if(num[a]==num[b]+num[c])
{
can=true;
way[a][][]++;
way[a][way[a][][]][]=b;
way[a][way[a][][]][]=c;
}
if(!can) { printf("-1"); return ; }
}
int tot=<<n;
for(int i=;i<tot;i++) sum[i]=count(i);
int b,c,j,news;
int now=,last=;
int minans=;
state[][]=state[][]=;
for(int a=;a<=n;a++)
{
state[now][]=;
for(int k=;k<=state[last][];k++)
{
j=state[last][k];
if(minans<sum[j]) continue;
minans=min(minans,sum[j]+n-a+);
can=false;
for(int i=;i<=way[a][][];i++)
{
b=way[a][i][];
c=way[a][i][];
if((j & <<b-) && (j & <<c-))
{
can=true;
break;
}
}
if(!can) continue;
for(int i=;i<=n;i++)
if(j & <<i-)
{
news=j ^ <<i- | <<a-;
if(vis[news]!=a)
{
state[now][++state[now][]]=news;
vis[news]=a;
}
}
news=j ^ <<a-;
if(vis[news]!=a)
{
state[now][++state[now][]]=news;
vis[news]=a;
}
}
swap(now,last);
}
int ans=;
for(int i=;i<=state[last][];i++) ans=min(ans,sum[state[last][i]]);
printf("%d",ans);
}
c

所有球无论怎么碰撞,他们的顺序不变
所以先对所有的小球排序
然后枚举相邻两个小球,计算出即将最早碰撞的两个球所需时间t
让所有的球都移动t时间,改变两个球的速度
重复枚举直到没有球会发生碰撞或超过时间
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
int m,id;
double x,v;
}e[];
bool cmp(node p,node q)
{
return p.x<q.x;
}
bool cmp2(node p,node q)
{
return p.id<q.id;
}
double v1(int i,int j)
{
return ((e[i].m-e[j].m)*e[i].v+*e[j].m*e[j].v)/(e[i].m+e[j].m);
}
double v2(int i,int j)
{
return ((e[j].m-e[i].m)*e[j].v+*e[i].m*e[i].v)/(e[i].m+e[j].m);
}
int main()
{
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
int n,k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%lf%lf%d",&e[i].x,&e[i].v,&e[i].m),e[i].id=i;
sort(e+,e+n+,cmp);
int a,b;
double delta,now,tmp,va,vb ;
while()
{
delta=2e9;
for(int i=;i<n;i++)
for(int j=i+;j<=n;j++)
{
if(e[i].v> && e[j].v> && e[i].v<e[j].v) continue;
if(e[i].v< && e[j].v>) continue;
if(e[i].v< && e[j].v< && e[i].v<e[j].v) continue;
tmp=(e[j].x-e[i].x)/(e[i].v-e[j].v);
if(tmp<delta) delta=tmp,a=i,b=j;
}
if(now+delta>k) break;
for(int i=;i<=n;i++) e[i].x+=delta*e[i].v;
va=v1(a,b);
vb=v2(a,b);
e[a].v=va; e[b].v=vb;
now+=delta;
}
delta=k-now;
for(int i=;i<=n;i++) e[i].x+=delta*e[i].v;
sort(e+,e+n+,cmp2);
for(int i=;i<=n;i++) printf("%.3lf\n",e[i].x);
}
2017 济南综合班 Day 7的更多相关文章
- 2017 济南综合班 Day 6
循环移动 (cyclic.cpp/c/pas) (1s/256M) 问题描述 给出一个字符串S与N个操作.每个操作用三元组(L, R, K)进行描述:操作将字符串第L个到第R个位置构成的子串循环移动K ...
- 2017 济南综合班 Day 5
毕业考试 (exam.cpp/c/pas) (1s/256M) 问题描述 快毕业了,Barry希望能通过期末的N门考试来顺利毕业.如果他的N门考试平均分能够达到V分,则他能够成功毕业.现在已知每门的分 ...
- 2017 济南综合班 Day 4
T1 外星人 二维前缀和 #include<cstdio> #define N 1001 using namespace std; bool v[N][N]; int sum[N][N]; ...
- 2017 济南综合班 Day 3
T1 黑化 题意: 求一个字符串是否可能包含另一个字符串 字符串中的?可以匹配任意字母 可能输出 God bless You! 一定不可能 输出 Game Over! 计算fail数组时,fail数 ...
- 2017 济南综合班 Day 2
木棍(stick) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有很多木棍,具体的,总共有n根,且每根木棍都有一个长度.为了方便起见,我们可以用一个正 ...
- 2017 济南综合班 Day 1
送分题(songfen) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK喜欢干一些有挑战的事,比如说求区间最大子段和.它知道这个题目有O(n)的做法.于 ...
- 2017 济南精英班 Day1
不管怎么掰都是n*m-1 #include<cstdio> using namespace std; int main() { freopen("bpmp.in",&q ...
- JavaScript脚本语言基础(四)
导读: JavaScript和DOM DOM文档对象常用方法和属性 DOW文档对象运用 JSON数据交换格式 正则表达式 1.JavaScript和DOM [返回] 文档对象模型(Document O ...
- JeeSite(2):导入数据,进入系统
本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/50954485 未经博主同意不得转载. 博主地址是:http://blog.csd ...
随机推荐
- 如何让thinkpad X1C 用U盘 安装上专业版win10
1 BIOS内置了文件 会导致win10 iso默认装家庭版 2 给iso 的resouse 目录中增加文件ei.cfg 3 内容如下 [EditionID]Professional[Channel] ...
- 二:HDFS 命令指南
命令具体选项请参考: http://hadoop.apache.org/docs/r2.6.3/hadoop-project-dist/hadoop-hdfs/HDFSCommands.html ...
- nodejs笔记--与Redis的交互篇(六)
原文地址:http://www.cnblogs.com/zhongweiv/p/node_redis.html 安装前准备 win64: Install python: http://www.pyth ...
- Sail
DescriptionThe polar bears are going fishing. They plan to sail from (sx,?sy) to (ex,?ey). However, ...
- 第三次寒假作业 sketch 了解
什么是sketch? sketch 是一种基于散列的数据结构,可以在高速网络环境中,实时地存储流量特征信息,只占用较小的空间资源,并且具备在理论上可证明的估计精度与内存的平衡特性. 通过设置散列函数, ...
- Redis源码剖析
Redis源码剖析和注释(一)---链表结构 Redis源码剖析和注释(二)--- 简单动态字符串 Redis源码剖析和注释(三)--- Redis 字典结构 Redis源码剖析和注释(四)--- 跳 ...
- f-measure[转]
F-Measure又称为F-Score,是IP(信息检索)领域常用的一个评价标准,计算公式为: 其中β是参数,P是准确率(Precision),R是召回率(Recall). F1-Measure:当参 ...
- 三节点搭建openstack-Mitaka版本
前言: 现在的云计算平台已经非常火,也非常的稳定了.像阿里云平台,百度云平台等等,今天咱们基于openstack来搭建一个云平台 注意: 本次平台搭建为三节点搭建(没有外部存储节点,所有存储为本地存储 ...
- hdu 3191 How Many Paths Are There (次短路径数)
How Many Paths Are There Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- 【题解】洛谷P3709大爷的字符串题
最近想要练习一下莫队(实在是掌握的太不熟练了啊.)这题一开始看到有点懵(题面杀),后来发现是要求众数的个数.乍一看好像很难的样子. 但仔细分析一下:首先往序列当中加入一个数,这个是很简单的,只需要维护 ...