美团CodeM复赛 02,03-程序员宅基地

技术标签: 数据结构与算法  

02 城市网络
比赛时候写的是单调栈,真的是让人见笑了,基本思路就是dfs时候动态处理单调栈(带回溯),然后离线处理答案。题解是用了倍增的,效率高很多

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
#define MP(x, y) make_pair(x, y)
#define lson l,m, rt<<1
#define rson m+1, r, rt<<1|1
const int N = 1e5+5;
const int INF = 0x3f3f3f3f;

int A[N];
struct Node{
    int to, nx;
}E[N * 2];
int Deep[N];
int head[N], tot;
void add(int fr, int to) {
    E[tot].to = to; E[tot].nx = head[fr]; head[fr] = tot ++;
}
struct Pode{
    int po, val, an;
    Pode(int a=0, int b=0, int c=0):po(a), val(b), an(c){}
};
vector<Pode> ask[N];
int ans[N];

int SA[N]; int SB[N]; int cnt;
int search(int x, int ty) {
    int l = 1; int r = cnt;
    while(l <= r) {
        int mid = (l + r) >> 1;
        if(ty) {
          if(SA[mid] >= x) r = mid - 1;
            else l = mid + 1;
        }else {
            if(-SB[mid] >= -x) r = mid-1;
            else l = mid + 1;
        }
    }
    return l;
}
void dfs(int x, int pre, int dep) {
    Deep[x] = dep;
    vector<pair<int, int> > tmp;
    if(cnt == 0) SA[++cnt] = dep, SB[cnt] = A[x];
    else {
        int pos = 0;
        for(int i = cnt; i >= 1; --i) {
            if(SB[i] > A[x]) {
                pos = i;
                SA[i + 1] = dep; SB[i + 1] = A[x]; cnt = i+1;
                break;
            }else {
                tmp.push_back(MP(SA[i], SB[i]));
            }
        }
        if(pos == 0) SA[1] = dep, SB[1] = A[x], cnt = 1;
    }
//  printf("%d: ", x); for(int i = 1; i <= cnt; ++i) printf("%d:%d ", SA[i], SB[i]); printf("\n");

    for(int i = 0; i < ask[x].size(); ++i) {
        int po = ask[x][i].po; int val = ask[x][i].val; int an = ask[x][i].an;
        int pos1 = search(Deep[po], 1); int pos2 = search(val, 0);
        ans[an] = max(pos2 - pos1, 0);
    }


    for(int i = head[x]; ~i; i = E[i].nx) {
        int to = E[i].to; if(to == pre) continue;
        dfs(to, x, dep + 1);
    }
    cnt --;
    for(int i = tmp.size() - 1; i >= 0; --i) {
        int t1 = tmp[i].first; int t2 = tmp[i].second;
        SA[++cnt] = t1; SB[cnt] = t2; 
    }
    tmp.clear();
}
int main() {
    int n, q;
    while(~scanf("%d %d", &n, &q)) {
        cnt = 0;
        memset(head, -1, sizeof(head)); tot = 0;

        for(int i = 1; i <= n; ++i) ask[i].clear();
        for(int i = 1; i <= n; ++i) scanf("%d", &A[i]);
        for(int i = 1; i < n; ++i) {
            int a, b; scanf("%d %d", &a, &b);
            add(a, b); add(b, a);
        }

        for(int i = 0; i < q; ++i) {
            int a, b, c; scanf("%d %d %d", &a, &b, &c);
            ask[a].push_back(Pode(b, c, i));
        }
        dfs(1, 1, 1);
    //  for(int i = 1; i <= n; ++i) printf("%d ", Deep[i]); printf("\n");
        for(int i = 0; i < q; ++i) printf("%d\n", ans[i]);
    }
    return 0;
}

03 神秘代码
比赛最后10分钟我才想到这就是一个环套树,然后就没有然后了= =,如果能A的话还是很有希望进前50的,我之前认为这题看起来像数论,又那么像拓展欧几里得,不会不会,还不如多试试05。确实弱233

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
#define MP(x, y) make_pair(x, y)
#define lson l,m, rt<<1
#define rson m+1, r, rt<<1|1
const int N = 1e5+5;
const int INF = 0x3f3f3f3f;
int MOD;

struct Node{
    int fr, to, nx, a, b, c;
}E[N << 1];
int head[N]; int tot;
int vis[N]; int Pre[N];
int suc;
int ans[N];
void add(int fr, int to, int a, int b, int c) {
    E[tot].to = to; E[tot].a = a; E[tot].b = b; E[tot].c = c; E[tot].fr = fr;
    E[tot].nx = head[fr]; head[fr] = tot ++;
}
long long inv(long long a) {
    if(a == 1) return 1;
    return inv(MOD%a)*(MOD-MOD/a)% MOD; 
}
void bfs(int x) {
    queue<int> Q;
    Q.push(x);
    vis[x] = 2;
    while(!Q.empty()) {
        int po = Q.front(); Q.pop();
    //  printf("%d: %d\n", po, ans[po]);
        for(int i = head[po]; ~i; i = E[i].nx) {
            int y = E[i].to; int a = E[i].a; int b = E[i].b; int c = E[i].c;
            if(vis[y] != 2) {
                vis[y] = 2;
                ll tt = inv(b);
                ans[y] = (1ll*c*tt %MOD - 1ll*a*ans[po]%MOD * tt %MOD + MOD) %MOD;
                Q.push(y);
            }
        }
    }
}


void Find(int x, int tar, int B, int C) {
    int Next = E[Pre[x]].fr; int a = E[Pre[x]].b; int b = E[Pre[x]].a; int c = E[Pre[x]].c;
    ll tmp = inv(a);

    //  printf("a:%d b:%d c:%d Next:%d now:%d %lld %d %d\n", a,b,c, Next, x, tmp, B, C);
    b = 1ll* (-b+MOD) * tmp %MOD;
    c = 1ll* c * tmp %MOD;
    C = (1ll*C + 1ll*B*c) % MOD;
    B = 1ll* B*b %MOD;
    if(Next == tar) {
        ans[tar] = 1ll* C*inv( (1-B+MOD)%MOD ) % MOD;
        //  printf("tar: %d\n", ans[tar]);
        bfs(tar);
        return; 
    }
    Find(Next, tar, B, C);
}
void dfs(int x, int pre) {
    if(suc) return;
    for(int i = head[x]; ~i; i = E[i].nx) {
        int to = E[i].to; if(to == pre) continue;
        if(suc) return;
        if(!vis[to]) { vis[to] = 1; Pre[to] = i; dfs(to, x); }
        else {
            Pre[to] = i;
            Find(to, to, 1, 0);
            suc = 1; 
            break;
        }
    }
}


int main() {
    int n;
    while(~scanf("%d %d", &n, &MOD)) {
        memset(head, -1, sizeof(head));
        tot = 0;

        for(int i = 0; i < n; ++i) {
            int u, v, a, b, c;
            scanf("%d %d %d %d %d", &u, &v, &a, &b, &c);
            add(u, v, a, b, c);
            add(v, u, b, a, c);
        }

        for(int i = 1; i <= n; ++i) {
            if(!vis[i]) {
                suc = 0;
                vis[i] = 1; dfs(i, i);
            }
        }
        for(int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
    }   
    return 0;
}

转载于:https://www.cnblogs.com/Basasuya/p/8433693.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/diankeng5481/article/details/101746782

智能推荐

linux查看端口命令_liunx中如何查端口号命令-程序员宅基地

文章浏览阅读1.4k次。netstat -an|grep 80 查看80端口进程列表_liunx中如何查端口号命令

jmeter学习记录(1)接口之间的动态关联--同一个线程组_jmeter中线程组session一致-程序员宅基地

文章浏览阅读699次。多个http请求处于同一个线程组内,可以通过正则表达式提取数据(必要时需要用v函数拼接),然后直接引用变量到下一个接口即可一、业务场景:测试过程中,有时下一个接口需要用到上一个接口的参数,我们要按照业务逻辑进行动态关联。做接口测试时候,尤其碰到某个接口需要用到上一个接口的数据,那我们就需要用到提取器来提取我们需要的数据,然后为下一个接口所用,其实就是在动态关联的时候需要用到。我最近在做接口测试过程中,正好用到了正则表达式提取数据和使用v函数拼接后,在下个接口中引用变量的场景,把整个过程记录下来,免得_jmeter中线程组session一致

libcurl 的 curl_easy_setopt()_curlopt_ssl_verifypeer-程序员宅基地

文章浏览阅读836次。CURL *hCurl = curl_easy_init();curl_easy_setopt(hCurl, CURLOPT_SSL_VERIFYPEER, 1L);curl_easy_setopt(hCurl, CURLOPT_SSL_VERIFYHOST, 2L);1、HTTPS相关(1)CURL_VERIFY_PEER默认值为1,该参数表示是否验证HTTPS证书的合法性,就是用第三方证书机构颁发的CA数字证书来解密服务端返回的证书,来验证其合法性。可在编译时就将CA数字证书编译进去,._curlopt_ssl_verifypeer

机器视觉工业缺陷检测的那些事(一、光源)_1.单选题对于表面不反光物体,采用下列哪种入射角度的光源比较好a高角度照射b-程序员宅基地

文章浏览阅读1.4w次,点赞48次,收藏324次。机器视觉工业缺陷检测的那些事(一) 视觉工业检测大体分为工件尺寸测量与定位,和表面缺陷检测,及各种Logo标识的检测与识别等。尺寸测量主要是检测物体的长、宽、高,比较常见主要是物体的二维尺寸(宽和高)检测。表面缺陷检测主要是物体表面局部物理或者化学性质不均匀的区域,比较常见的有金属或者塑料制品表面的划痕(如:手机壳/屏幕表面的划痕)、斑点和孔洞(如:PCB板漏了焊点或者表面多了焊点),纸张表面的色差、脏污点、破损,纸制品表面的压痕、凸起,玻璃等非金属制品表面的杂质、破损、污点、平整度等..._1.单选题对于表面不反光物体,采用下列哪种入射角度的光源比较好a高角度照射b

AO4621-VB一款N+P—Channel沟道SOP8的MOSFET晶体管参数介绍与应用说明-程序员宅基地

文章浏览阅读123次,点赞4次,收藏2次。在不同的栅极-源极电压下,低RDS(ON)值分别为28mΩ和51mΩ,确保高效的功率管理。利用其高电压额定值、电流承载能力和低导通电阻,AO4621-VB为不同行业和应用提供了一种多功能的功率管理解决方案。4. 电池管理:在电动车辆、太阳能系统和便携设备等电池管理系统中,AO4621-VB可以处理高电流并提供可靠性能。1. 电机控制:AO4621-VB可用于电器、机器人和工业机械等电机控制电路,具有高电流承载能力和低导通电阻。5. 音频放大器:可用于音箱和耳机等音频放大电路,确保低失真和高保真音频输出。

北斗GPS车辆监控管理系统_北斗设备管理字段-程序员宅基地

文章浏览阅读335次。监控中心是在整个系统的“神经中枢”,集中实现监控、调度、接/处警,图像处理功能和其他信息服务,并对整个系统的软硬件进行协调、管理。●防盗报警:设备提供和原车防盗器对接的自定义检测线束,防盗器发出盗,报警数据上传到中心。●(可选)自定义报警:由用户根据需要连接各种检测开关,触发报警,例如防盗器报警。●自定义报警:支持1-2路自定义报警,如卸料是报警,车辆要接检测开关;●自定义报警:支持1-2路自定义报警,如卸料是报警,车辆要接检测开关;●紧急报警:驾驶员危险时按报警开关报警,中心必须人工干预才能取消;_北斗设备管理字段

随便推点

pr 基本操作_pr基本操作-程序员宅基地

文章浏览阅读5.3k次,点赞2次,收藏16次。1、文件夹直接拖、项目面板双击,导入单个或者多个,或者文件夹;项目左下角,改变视图;项目右下脚,可新建文件夹管理(素材箱);导入图片时,选择是否分层,因为图片从ps编辑时,可能有多个图层;当分层导入时,会比图层数目多一个,是序列;导入序列帧:是以帧为单位的一系列图片,但是直接导入是图片,因此以序列帧格式导入,才能是视频; 导入时,选中第一个,根据命名,电脑会直接识别序列帧,勾选左下脚:“图像序列”;序列帧命名时, 注意位数;07、脱机008 文件序列的创建创建序列,项目右下角 序列_pr基本操作

ORACLE OC4J服务器不支持XFire webservices的解决方案-程序员宅基地

文章浏览阅读63次。为什么80%的码农都做不了架构师?>>> ..._oracle请求xfire内容缺失

JAVA环境变量的配置_"c:\\program files\\java\\jdk1.8.0_212\\bin\\java.-程序员宅基地

文章浏览阅读1.1k次。一:jdk安装版本——1.8.0_171step:默认开发工具,默认文件路劲二:jdk变量三个1_"c:\\program files\\java\\jdk1.8.0_212\\bin\\java.exe\" -xx:tieredstopatlevel=1 -n"

SynchronizedMap和ConcurrentHashMap有什么区别-程序员宅基地

文章浏览阅读734次。SynchronizedMap实现上在调用Map的所有方法是,对整个map进行了同步!public V put(K key, V value) { synchronized (mutex) {return m.put(key, value);}}ConcurrentHashMap的实现却更加精细,他对要操作的桶加锁,而不是整个加锁,所以ConcurrentHashMap在性能..._sequencedhashmap 和 concurrenthashmap 区别是什么

二、SpringBoot2核心功能--04单元测试--01-JUnit5单元测试及其注解-程序员宅基地

文章浏览阅读815次,点赞14次,收藏30次。JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。@Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试。: 由于JUint已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。: Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。

signature=f326654ec2c650c08589c4b3d37549aa,Squashed commit of the following:-程序员宅基地

文章浏览阅读4.1k次。commit 06145230c833c3db5dab8858e11bcd550a37c57fAuthor: Nick Coghlan Date: Thu Aug 29 23:26:53 2019 +1000bpo-37947: Avoid double-decrement in symtable recursion counting (GH-15593)With `symtable_visi..._squashed commit of the following:

推荐文章

热门文章

相关标签