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的更多相关文章

  1. 2017 济南综合班 Day 6

    循环移动 (cyclic.cpp/c/pas) (1s/256M) 问题描述 给出一个字符串S与N个操作.每个操作用三元组(L, R, K)进行描述:操作将字符串第L个到第R个位置构成的子串循环移动K ...

  2. 2017 济南综合班 Day 5

    毕业考试 (exam.cpp/c/pas) (1s/256M) 问题描述 快毕业了,Barry希望能通过期末的N门考试来顺利毕业.如果他的N门考试平均分能够达到V分,则他能够成功毕业.现在已知每门的分 ...

  3. 2017 济南综合班 Day 4

    T1 外星人 二维前缀和 #include<cstdio> #define N 1001 using namespace std; bool v[N][N]; int sum[N][N]; ...

  4. 2017 济南综合班 Day 3

    T1  黑化 题意: 求一个字符串是否可能包含另一个字符串 字符串中的?可以匹配任意字母 可能输出 God bless You! 一定不可能 输出 Game Over! 计算fail数组时,fail数 ...

  5. 2017 济南综合班 Day 2

    木棍(stick) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有很多木棍,具体的,总共有n根,且每根木棍都有一个长度.为了方便起见,我们可以用一个正 ...

  6. 2017 济南综合班 Day 1

    送分题(songfen) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK喜欢干一些有挑战的事,比如说求区间最大子段和.它知道这个题目有O(n)的做法.于 ...

  7. 2017 济南精英班 Day1

    不管怎么掰都是n*m-1 #include<cstdio> using namespace std; int main() { freopen("bpmp.in",&q ...

  8. JavaScript脚本语言基础(四)

    导读: JavaScript和DOM DOM文档对象常用方法和属性 DOW文档对象运用 JSON数据交换格式 正则表达式 1.JavaScript和DOM [返回] 文档对象模型(Document O ...

  9. JeeSite(2):导入数据,进入系统

    本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/50954485 未经博主同意不得转载. 博主地址是:http://blog.csd ...

随机推荐

  1. 【python】scrapy相关

    目前scrapy还不支持python3,python2.7与python3.5共存时安装scrapy后,执行scrapy后报错 Traceback (most recent call last): F ...

  2. CP文件覆盖问题

    # \cp -r -a aaa/* /bbb[这次是完美的,没有提示按Y.传递了目录属性.没有略过目录]

  3. ArrayList中modCount的作用

    在ArrayList中有个成员变量modCount,继承于AbstractList. 这个成员变量记录着集合的修改次数,也就每次add或者remove它的值都会加1.这到底有什么用呢? 先看下面一段测 ...

  4. CSS3制作各种形状图像(转)

    CSS3制作各种形状图像 浏览:1417 | 更新:2015-05-24 14:43 | 标签:css 1 2 3 4 5 6 7 分步阅读 圆形-椭圆形-三角形-倒三角形=左三角形-右三角形-菱形- ...

  5. python学习笔记02:运行python程序

    1.启动cmd命令行,输入python后回车,运行python解释器: 输入python代码后回车: print('Hello World')

  6. TCP系列19—重传—9、thin stream下的重传

    一.介绍 当TCP连续大量的发送数据的时候,当出现丢包的时候可以有足够的dup ACK来触发快速重传.但是internet上还有大量的交互式服务,这类服务一般都是由小包组成,而且一次操作中需要传输的数 ...

  7. spring ioc经典总结

    component-scan标签默认情况下自动扫描指定路径下的包(含所有子包),将带有 @Component @Repository @Service @Controller标签的类自动注册到spri ...

  8. SQL SERVER技术内幕之4 子查询

    最外层查询的结果集会返回给调用者,称为外部查询.内部查询的结果是供外部查询使用的,也称为子查询.子查询可以分成独立子查询和相关子查询两类.独立子查询不依赖于它所属的外部查询,而相关子查询则须依赖它所属 ...

  9. Windows API封装:LoadLibrary/FreeLibrary

    LoadLibrary/LoadLibraryEx用来加载DLL到自己的进程空间,使用完用FreeLibrary释放,一般使用方式如下:    HINSTANCE hInstRich = ::Load ...

  10. 面试:谈谈你对jQuery的理解

    jQuery是一个轻量级的javascript框架,极大的简化了js的编程. 1.首先jQuery提供了强大的元素选择器.用于获取html页面中封装了html元素的jQuery对象.像常见的选择器有: ...