0

0

Codeforces Round #148 (Div. 1)_html/css_WEB-ITnose

php中文网

php中文网

发布时间:2016-06-24 11:54:46

|

1305人浏览过

|

来源于php中文网

原创


Unreal Images
Unreal Images

免费的AI图片库

下载

A


wool sequence 表示一个序列中可以找到一个连续的子区间使得区间异或值为0

那么求的是不含这种情况的序列个数

立即学习前端免费学习笔记(深入)”;

题目中数据范围是,在0~2^m - 1中选n个数作为一个序列 

n和m都是10^5


仔细思考一下。

第一位 有2^m-1种情况

第二位由于不能跟其一样  有2^m-2种情况

第三位由于不能跟第二位一样,并且不能跟前两位的异或值一样,有2^m-3种情况

依次类推,得到公式

(2^m-1)*(2^m-2)*...*(2^m-n)

int mod = 1000000009;int main(){    int n, m;    scanf("%d%d", &n, &m);    if(m < 20 && (1 << m) <= n ) {        printf("0\n");        return 0;    }    long long ans = 1;    for(int i = 0; i < m; i++) {        ans = ans * 2LL % mod;    }    long long res = 1;    for(int i = 1; i <= n; i++) {        long long tmp = ans - i;        if(tmp < 0) tmp += mod;        res = res * tmp % mod;    }    printf("%I64d\n", res);    return 0;}



B

给出一个序列a和一个数值h

将序列划分为两部分,某部分可以为空

然后f函数式这么计算

如果两个数在同个部分

f函数的值就是两个数的和

不在同部分就两个数的和加上h

求一种划分使得f函数的最大值和最小值的差值最小


有一种贪心方案, 

就是f的最大值一定跟序列中最大的几个有关

最小值一定跟序列中最小的几个有关

这里我取得最小的5个和最大的5个

直接枚举放第一部分或者第二部分即可


为啥这样可以

仔细想一下。

可以发现其他的任何情形都没有这种情况下优


int n, h;struct node {    int x, id;}p[111111], tmp[15];int ans[111111];bool cmp(node x, node y) {    return x.x < y.x;}vector<node>lft, rht;int main(){    scanf("%d%d", &n, &h);    for(int i = 0; i < n; i++) {        scanf("%d", &p[i].x);        p[i].id = i;    }    sort(p, p + n, cmp);     int cnt = 0;    if(n > 10) {        for(int i = 0; i < 5; i++) tmp[cnt++] = p[i];        for(int i = n - 5; i < n; i++) tmp[cnt++] = p[i];    } else {        cnt = n;        for(int i = 0; i < n; i++) tmp[i] = p[i];    }    int vs[12];    int d = INF;    int num = 0;    for(int i = 0; i < (1 << cnt); i++) {        lft.clear();        rht.clear();        for(int j = 0; j < cnt; j++) {            node x = tmp[j];            if((1 << j) & i) {                lft.push_back(x);            } else rht.push_back(x);        }        int mx = 0;        int mi = INF;        int sz1 = lft.size();        for(int j = 0; j < sz1; j++) {            for(int k = j + 1; k < sz1; k++) {                mx = max(mx, lft[j].x + lft[k].x);                mi = min(mi, lft[j].x + lft[k].x);            }        }        int sz2 = rht.size();        for(int j = 0; j < sz2; j++) {            for(int k = j + 1; k < sz2; k++) {                mx = max(mx, rht[j].x + rht[k].x);                mi = min(mi, rht[j].x + rht[k].x);            }        }        for(int j = 0; j < sz1; j++) {            for(int k = 0; k < sz2; k++) {                mx = max(mx, lft[j].x + rht[k].x + h);                mi = min(mi, lft[j].x + rht[k].x + h);            }        }        if(d > mx - mi) {            d = mx - mi;            num = 0;            for(int j = 0; j < sz1; j++) vs[num++] = lft[j].id;        }    }    printf("%d\n", d);    for(int i = 0; i < n; i++) ans[i] = 2;    for(int i = 0; i < num; i++) ans[vs[i]] = 1;    for(int i = 0; i < n; i++) printf("%d ", ans[i]);    printf("\n");    return 0;}


C

一颗无根树

有向边

从树上不多于两个点出发,遍历所有的点,

问需要改变最少多少个有向边的方向

那么就是一个树dp了

枚举根作为第一个点,

然后第二个点就需要dp

从根往下遍历所有的点的话,需要修改边的方向很容易算出来,每个点访问自己所有子树需要修改的边数也很容易算

然后数组开 dp[n][2]

dp[u][0]代表从u走到根需要修改多少边

dp[u][1]表示从跟走到u需要修改多少边


struct node {    int v, w;    node() {}    node(int _v, int _w) {v = _v; w = _w;}};vector<node> g[3333];int ss[3333], dp[3333][2];int total;void dfs0(int u, int f, int x) {    total += x;    ss[u] = ss[f] + x;    int sz = g[u].size();    for(int i = 0; i < sz; i++) {        int v = g[u][i].v;        int w = g[u][i].w;        if(v == f) continue;        dfs0(v, u, w);    }}void dfs(int u, int f, int x) {    if(f == 0) {        dp[u][0] = dp[u][1] = 0;    } else {        dp[u][1] = dp[f][1] + x;        dp[u][0] = min(dp[f][0], dp[f][1]) + !x;    }    int sz = g[u].size();    for(int i = 0; i < sz; i++) {        int v = g[u][i].v;        int w = g[u][i].w;        if(v == f) continue;        dfs(v, u, w);    }}int n;int main(){    int u, v;    scanf("%d", &n);    for(int i = 1; i <= n; i++) g[i].clear();    for(int i = 1; i < n; i++) {        scanf("%d%d", &u, &v);        g[u].push_back(node(v, 0));        g[v].push_back(node(u, 1));    }    int ans = INF;    for(int i = 1; i <= n; i++) {        ss[i] = 0;        total = 0;        dfs0(i, 0, 0);        dfs(i, 0, 0);        for(int j = 1; j <= n; j++) ans = min(ans, total - ss[j] + min(dp[j][0], dp[j][1]));    }    printf("%d\n", ans);    return 0;}



D.

留坑  不会


E

看了ACMonster的才大约懂做,其实还是很模糊


有个有向图,边的长度都一样

n

有个人要从起点到终点去,必须做公交

然后有若干辆公交  有各自的起点和终点

保证每秒都有一辆公交发出,意思就是那个人一到某个点就可以换乘相应的公交

然后这些公交很奇怪, 从自己的起点到终点,它会随机走一条最短路径过去

现在问,最小的(他在最坏情况下的换乘次数)

就是寻找一条线路使得他在最坏情况下换乘bus的次数最小


这个由于是求换乘次数,所以这个图就没法按dag那种dp方法

首先预处理任意两点间的最短路

然后把每个点必然经过的公交线路存下来

然后就倒着dp

从终点往起点dp

非常之暴力

令dp[i][j]表示人在点i在j车上时最小的换乘次数

但是有两种情况

一种是这个点一定在这个公交线路上

一种是这个点可能会在这个公交线路上或者就不在这个公交线路上

第一种情况是最终的合法解

第二种用来辅助第一种


然后更新的时候,对于每个点,枚举公交车,然后看这个点的邻接点,相对于这个路径是不是合法的,意思就是邻接点离该路径的终点应该是更近一步的,

即使这个点不会出现在这个公交路径上,也要更新,这是为了让那些后面的关键的点可以更新到,其实就相当于虚拟了一下,将这个公交的线路给延伸了

对于这些合法的邻接点, 选择一条最糟糕的

然后枚举换乘的时候,就必须是这个点一定在这个公交线路上,  因为换乘一定是在这些点上才能换乘,不然最糟糕的情况是等不到车的

然后如果有最优值被更新,那么整个dp再重复这个过程 


int dis[111][111], dp[111][111];vector<int>g[111], bus[111];int bx[111], by[111], m, n, t, src, des;bool pass[111][111];int main(){    int u, v;    scanf("%d%d%d%d", &n, &m, &src, &des);    for(int i = 1; i <= n; i++)        for(int j = 1; j <= n; j++)            if(i != j) dis[i][j] = INF;    for(int i = 0; i < m; i++) {        scanf("%d%d", &u, &v);        dis[u][v] = 1;        g[u].push_back(v);    }    for(int k = 1; k <= n; k++) {        for(int i = 1; i <= n; i++) {            for(int j = 1; j <= n; j++)                if(dis[i][j] > dis[i][k] + dis[k][j])                    dis[i][j] = dis[i][k] + dis[k][j];        }    }    m = 0;    scanf("%d", &t);    while(t--) {        scanf("%d%d", &u, &v);        if(dis[u][v] != INF) {            m++;            bx[m] = u;            by[m] = v;        }    }    for(int i = 1; i <= m; i++) {        u = bx[i], v = by[i];        for(int j = 1; j <= n; j++) {            if(dis[u][v] == dis[u][j] + dis[j][v]) pass[i][j] = 1;            for(int k = 1; k <= n; k++) {                if(k != j && dis[u][k] == dis[u][j] && dis[k][v] == dis[j][v]) {                    pass[i][j] = 0;                    break;                }            }            if(pass[i][j]) bus[j].push_back(i);        }    }    for(int i = 1; i <= n; i++) {        for(int j = 1; j <= m; j++) {            if(i == des && pass[j][i]) dp[i][j] = 0;            else dp[i][j] = INF;        }    }    bool flag = 1;    while(flag) {        flag = 0;        for(int i = 1; i <= n; i++) {            for(int j = 1; j <= m; j++) {                int mx = -1;                for(int k = 0; k < g[i].size(); k++) {                    v = g[i][k];                    if(dis[i][by[j]] != dis[v][by[j]] + 1) continue;                    //if(!pass[j][i] || !pass[j][v]) continue;                    mx = max(mx, dp[v][j]);                }                if(mx != -1 && mx < dp[i][j]) {                    dp[i][j] = mx;                    flag = 1;                }                for(int k = 0; k < bus[i].size(); k++) {                    v = bus[i][k];                    if(dp[i][v] + 1 < dp[i][j]) {                        dp[i][j] = dp[i][v] + 1;                        flag = 1;                    }                }            }        }    }    int ans = INF;    for(int i = 1; i <= m; i++)        if(pass[i][src]) ans = min(ans, dp[src][i] + 1);    if(ans == INF) ans = -1;    printf("%d\n", ans);    return 0;}




HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

463

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

135

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

64

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

26

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

524

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

53

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号