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 ...
随机推荐
- ServiceStack.Ormlit 使用Insert的时候自增列不会被赋值
Insert签名是这样的,将第2个参数设置为true就会返回刚插入的自增列ID了,然后可以手工赋值到对象上面去 public static long Insert<T>(this IDbC ...
- *.hbm.xml作用是什么
实体与表的映射关系通过XML来描述的文件.在 hibernate.cfg.xml中管理,在项目启动的时候加载到内存. hbm指的是hibernate的映射文件 映射文件也称映射文档,用于向Hibern ...
- 常用linux命令相关
[查看端口] netstat -tlnp netstat命令 netstat -an | grep 3306 3306替换成需要grep的端口号 lsof命令 通过list open file命令可以 ...
- Python如何运行
Python是一种解释型语言,在执行Python的时,解释器将源代码source code翻译成字节码byte code,然后byte code交给Python虚拟机PVM去执行,整个流程如下图所示: ...
- Red and Black(DFS深搜实现)
Description There is a rectangular room, covered with square tiles. Each tile is colored either red ...
- mysql分页的limit优化
1.很多新人都会很纳闷,为什么我建了索引使用分页还是这么卡.好,现在让我们一步一步去找原因吧. 首先limit本身跟索引没有直接关系. 先建一张商品sku表 create table goods_sk ...
- matlab 直方图均衡化(含rgb)
步骤: 统计原图像素每个像素的个数 统计原图像<每个灰度级的像素的累积个数 家里灰度级得映射规则 将原图每个像素点的灰度映射到新图 代码: clear all I=imread('1.jpg') ...
- ACM 第十九天
积性函数 积性函数线性筛,筛素数,u(n),欧拉函数: vis[]=vis[]=,mu[]=,phi[]=; ;i<=N;++i){ ,phi[i]=i-,prime[++cnt]=i; ,k= ...
- C# Excel2007 导出生成 2003兼容格式
//导出2007格式 AppWb.Saved = true; //保存工作薄 AppExcel.ActiveWorkbook.SaveCopyAs(FilePath); //导出2003格式 AppW ...
- hadoop2.5.2学习及实践笔记(五)—— HDFS shell命令行常见操作
附:HDFS shell guide文档地址 http://hadoop.apache.org/docs/r2.5.2/hadoop-project-dist/hadoop-common/FileSy ...