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=0; while(x) { sum+=c1[x]; x-=x&-x; } return sum;
}
int query2(int x)
{
    int sum=0; 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=0,cnt=0;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),hash[i]=a[i];
    sort(hash+1,hash+n+1);
    tot=unique(hash+1,hash+n+1)-(hash+1);
    for(int i=1;i<=n;i++) a[i]=lower_bound(hash+1,hash+tot+1,a[i])-hash;
    int R=n;
    while(R>=1)
    {
        add2(a[R],1);
        cnt+=query2(a[R]-1);
        R--;
    }
    R++;
    for(int L=1;L<n;L++)
    {
        if(L==R)
        {
            cnt=cnt-(L-1-query1(a[R]))-query2(a[R]-1);
            add2(a[R++],-1);
        }
        cnt=cnt+L-1-query1(a[L])+query2(a[L]-1);
        add1(a[L],1);
        while(cnt>k && R<=n )
        {
            cnt=cnt-(L-query1(a[R]))-query2(a[R]-1);
            add2(a[R++],-1);
        }
        if(cnt<=k) ans+=n-R+1;
    }
    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[(1<<N)+2];
int n,num[N+1];
int way[N+1][625][2];
int state[2][(1<<N)+2];
int vis[(1<<N)+2];
int sum[(1<<N)+2];
int count(int x)
{
    int cnt=0;
    while(x) cnt+=x&1,x>>=1;
    return cnt;
}
int main()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&num[i]);
    bool can=false;
    for(int a=2;a<=n;a++)
    {
        can=false;
        for(int b=0;b<a;b++)
            for(int c=b;c<a;c++)
                if(num[a]==num[b]+num[c])
                {
                    can=true;
                    way[a][0][0]++;
                    way[a][way[a][0][0]][0]=b;
                    way[a][way[a][0][0]][1]=c;
                }
        if(!can)  { printf("-1"); return 0; }
    }
    int tot=1<<n;
    for(int i=0;i<tot;i++) sum[i]=count(i);
    int b,c,j,news;
    int now=0,last=1;
    int minans=30;
    state[1][0]=state[1][1]=1;
    for(int a=2;a<=n;a++)
    {
        state[now][0]=0;
        for(int k=1;k<=state[last][0];k++)
        {
            j=state[last][k];
            if(minans<sum[j]) continue;
            minans=min(minans,sum[j]+n-a+1);
            can=false;
            for(int i=1;i<=way[a][0][0];i++)
            {
                b=way[a][i][0];
                c=way[a][i][1];
                if((j & 1<<b-1) && (j & 1<<c-1))
                {
                    can=true;
                    break;
                }
            }
            if(!can) continue;
            for(int i=1;i<=n;i++)
            if(j & 1<<i-1)
            {
                news=j ^ 1<<i-1 | 1<<a-1;
                if(vis[news]!=a)
                {
                    state[now][++state[now][0]]=news;
                    vis[news]=a;
                }
            }
            news=j ^ 1<<a-1;
            if(vis[news]!=a)
            {
                state[now][++state[now][0]]=news;
                vis[news]=a;
            }
        }
        swap(now,last);
    }
    int ans=30;
    for(int i=1;i<=state[last][0];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[11];
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+2*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+2*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=1;i<=n;i++) scanf("%lf%lf%d",&e[i].x,&e[i].v,&e[i].m),e[i].id=i;
    sort(e+1,e+n+1,cmp);
    int a,b;
    double delta,now,tmp,va,vb ;
    while(1)
    {
        delta=2e9;
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
            {
                if(e[i].v>0 && e[j].v>0 && e[i].v<e[j].v) continue;
                if(e[i].v<0 && e[j].v>0) continue;
                if(e[i].v<0 && e[j].v<0 && 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=1;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=1;i<=n;i++) e[i].x+=delta*e[i].v;
    sort(e+1,e+n+1,cmp2);
    for(int i=1;i<=n;i++) printf("%.3lf\n",e[i].x);
}

时间: 2024-12-28 10:01:27

2017 济南综合班 Day 7的相关文章

2017 济南综合班 Day 5

毕业考试 (exam.cpp/c/pas) (1s/256M) 问题描述 快毕业了,Barry希望能通过期末的N门考试来顺利毕业.如果他的N门考试平均分能够达到V分,则他能够成功毕业.现在已知每门的分数不能够超过R:他的第i门考试目前得分为Ai,如果想要在这门科目增加一分则需要多写Bi篇论文.Barry想知道,如果想要毕业的话,他最少需要写多少篇论文? 输入格式(exam.in) 第一行三个整数,N, R, V,分别代表考试科目数,每门考试的最高分,需要达到的平均分. 接下来的N行每行两个整数A

2017 济南综合班 Day 4

T1 外星人 二维前缀和 #include<cstdio> #define N 1001 using namespace std; bool v[N][N]; int sum[N][N]; int main() { freopen("alien.in","r",stdin); freopen("alien.out","w",stdout); int r,c,p,q; scanf("%d%d%d%d&quo

2017 济南综合班 Day 3

T1  黑化 题意: 求一个字符串是否可能包含另一个字符串 字符串中的?可以匹配任意字母 可能输出 God bless You! 一定不可能 输出 Game Over! 计算fail数组时,fail数组不具有传递性 例: pqkbpqsbqszzpqkbpq?z 在z处失配后: pqkbpqsbqszz        pqkbpq?z z匹配成功,误认为包含 因为计算fail时,?匹配了 k,而匹配时 ?匹配了s s不和k匹配 即?不具有传递性 #include<cstdio> #includ

2017 济南综合班 Day 6

循环移动 (cyclic.cpp/c/pas) (1s/256M) 问题描述 给出一个字符串S与N个操作.每个操作用三元组(L, R, K)进行描述:操作将字符串第L个到第R个位置构成的子串循环移动K次.一次循环移动就是将字符串最后的这个字符移动到第一位,其余的字符顺次后移. 例如,对于字符串abacaba,操作(L=3, R=6, K=1)后得到的字符串即为abbacaa. 求出在N个操作后得到的字符串. 输入格式(cyclic.in) 第一行一个字符串S. 第二行一个整数N,代表操作的总数.

2017 济南精英班 Day1

不管怎么掰都是n*m-1 #include<cstdio> using namespace std; int main() { freopen("bpmp.in","r",stdin); freopen("bpmp.out","w",stdout); int n,m; scanf("%d%d",&n,&m); int ans=(1ll*n*m-1)%998244353; prin

罗森伯格再次荣获《2017年度综合布线十大品牌》以及《2017年度数据中心解决方案优秀供应商》两项大

"中国智能建筑品牌奖"由千家品牌实验室评选并颁发,综合了千家智客全年品牌监测数据.市场调查分析.用户反馈.专家评议以及用户投票等因素,评选出十大综合布线品牌等多项大奖.罗森伯格再次荣获<2017年度综合布线十大品牌>以及<2017年度数据中心解决方案优秀供应商>两项大奖. "中国智能建筑品牌奖"是智能建筑领域极具含金量的年度大奖,自2002年首次颁发,至今已有十五年的历史.由于评选客观.公正.权威,"中国智能建筑品牌奖"也

2017 济南集训DAY1.AF

LIST T1 水题(water) T2 梦境(dream) T2 动态规划(dp) T1 水题(water) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK出了道水题. 这个水题是这样的:有两副牌,每副牌都有n张. 对于第一副牌的每张牌长和宽分别是xi和yi.对于第二副牌的每张牌长和宽分别是aj和bj.第一副牌的第i张牌能覆盖第二副牌的第j张牌当且仅当xi>=aj并且yi>=bj.(注意牌不能翻转)当然一张牌只能去覆盖最多一张牌,而不能覆盖好多

如何解读梯形图编程原则?

如何解读梯形图编程原则?plc程序设计方法又是怎样的?与大家一起学习!! 梯形图编程原则与PLC程序设计方法 (1)  输入/输出继电器.内部辅助继电器.定时器.计数器等器件的触点可以多次重复使用,无需复杂的程序结构来减少触点的使用次数. (2) 梯形图每一行都是从左母线开始,线圈终止于右母线.触点不能放在线圈的右边,如下图所示 (3)除步进程序外,任何线圈.定时器.计数器.高级指令等不能直接与左母线相连. (4)在程序中,不允许同一编号的线圈两次输出(双线圈输出).下面的梯形图是不允许的. (

2017-2018-2 20179225 《密码与安全新技术专题》 第5周作业

2017-2018-2 <密码与安全新技术>第3周作业 课程:<密码与安全新技术> 班级:2017级92班 学号:20179225 上课教师:谢四江 主讲教师:王志强 上课日期:2018年5月10日 必修/选修: 必修 主要内容:基于模糊测试的漏洞挖掘及攻防技术 一.背景及意义 1 安全漏洞定义: 简单来说安全漏洞就为存在的缺陷与不足,使别人容易攻破或着入侵电脑. 精确定义:是指信息系统在设计.实现或者运行管理过程中存在的缺陷或不足,从而使攻击者能够在未授权的情况下利用这些缺陷破坏