排位Round2补题报告

排位Round2补题报告

T1

克鲁斯卡尔跑完最小生成树,把选中边放到edg里面,接着跑树链剖分的两遍DFS,建一颗线段树,直接查最小值就行了。

注意是边权线段树,权值放在深度打的点上。
还有就是查询的ID就是她本来的ID,用newid边查边错。
一开始心情爆炸没时间写这题了,其·实挺裸的。

#include <bits/stdc++.h>
#define nmax 200050
#define inf 1000000050
using namespace std;
int father[nmax];
int rnk[nmax];
struct myx{
    int form,to,val;
    int id;
    bool ischoosen;
}my[nmax];
struct edge{
    int to,next;
}edg[nmax<<2];
struct you{
    int from,to,val;
}you[nmax];
struct tree{
    int l,r,val;
    int mid(){
        return (l+r)>>1;
    }
}tree[nmax<<2];
int fa[nmax],son[nmax],sz[nmax],newid[nmax],hashback[nmax],dep[nmax],top[nmax];
int head[nmax],val;
int tot =0,num = 0;
int n,m;
void add(int u, int v){
    edg[tot].to = v;
    edg[tot].next = head[u];
    head[u] = tot++;
}
int findset(int x){
    int r  = x,temp;
    while(father[r] != r) r = father[r];
    while(x != r){
        temp = father[x];
        father[x] = r;
        x = temp;
    }
    return r;
}
void unionset(int x, int y){
    x = findset(x);
    y = findset(y);
    if(x == y) return;
    if(rnk[x] > rnk[y]){
        father[y] = x;
    }else{
        father[x] = y;
        if(rnk[x] == rnk[y])
            rnk[x] ++;
    }
}
bool cmp(myx a,myx b){
    if(a.val < b.val) return true;
    else return false;
}
void kelusikaer(){
    for(int i = 0;i<m;++i){
        int x = findset(my[i].form);
        int y = findset(my[i].to);
        if(x != y){
            you[++num].from = my[i].form;
            you[num].to = my[i].to;
            you[num].val = my[i].val;
            add(my[i].form,my[i].to);
            add(my[i].to,my[i].form);
            unionset(my[i].form,my[i].to);
            my[i].ischoosen = true;
        }
    }
}
void dfsFirst(int rt, int f,int d){
    dep[rt] = d;
    fa[rt] = f;
    sz[rt] = 1;
    for(int i = head[rt]; i!= -1; i = edg[i].next){
        int nxt = edg[i].to;
        if(nxt != f){
            dfsFirst(nxt,rt,d+1);
            sz[rt]+=sz[nxt];
            if(son[rt] == -1 || sz[nxt] > sz[son[rt]]){
                son[rt] = nxt;
            }
        }

    }
}
void dfsSecond(int rt, int tp){
    top[rt] = tp;
    newid[rt] = ++num;
    if(son[rt] == -1) return;
    dfsSecond(son[rt],tp);
    for(int i = head[rt];i != -1; i = edg[i].next){
        int nxt = edg[i].to;
        if(nxt != son[rt] && nxt != fa[rt])
            dfsSecond(nxt,nxt);
    }
}
void PushUp(int rt){
    tree[rt].val = min(tree[rt<<1].val , tree[rt<<1|1].val);
}
void Build(int l, int r, int rt){
    tree[rt].l = l; tree[rt].r = r;
    if(l == r){
        return;
    }
    Build(l,tree[rt].mid(),rt<<1);
    Build(tree[rt].mid()+1,r,rt<<1|1);
    PushUp(rt);
}
void UpdatePoint(int val, int pos, int rt){
    if(tree[rt].l == tree[rt].r){
        tree[rt].val = val ;
        return;
    }
    if(pos <= tree[rt].mid()) UpdatePoint(val,pos,rt<<1);
    else UpdatePoint(val,pos,rt<<1|1);
    PushUp(rt);
}
int QueryMIN(int l,int r,int rt){
    if(l <= tree[rt].l && tree[rt].r <= r) return tree[rt].val;
    int ans = inf;
    if(l <= tree[rt].mid()) ans = min(ans,QueryMIN(l,r,rt<<1));
    if(r > tree[rt].mid()) ans = min(ans,QueryMIN(l,r,rt<<1|1));
    return ans;
}
int Find_MIN(int x, int y){
    int tx = top[x],ty =top[y];
    int ans  = inf;
    while(tx != ty){
        if(dep[tx] < dep[ty]){
            swap(x,y);
            swap(tx,ty);
        }
        ans = min (QueryMIN(newid[tx],newid[x],1),ans);
        x = fa[tx]; tx = top[x];
    }
    if(x == y) return ans;
    if(dep[x] > dep[y]) swap(x,y);
    ans = min( QueryMIN(newid[son[x]],newid[y],1),ans);
    return ans;
}

bool cmp2(myx a, myx b){
    if(a.id < b.id) return true;
    else return false;
}
void init(){
    memset(tree,0,sizeof tree);
    memset(head,-1,sizeof head);
    memset(son,-1,sizeof son);
    memset(edg,0,sizeof edg);
    memset(hashback,0,sizeof hashback);
    memset(my,0,sizeof my);
    memset(you,0,sizeof you);
    tot = num = 0;
}
int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d %d",&n,&m) != EOF){
        init();
        for(int i = 1;i<n;++i) father[i] = i,rnk[i] = 0;
        for(int i = 0;i<m;++i) scanf("%d %d %d",&my[i].form,&my[i].to,&my[i].val),my[i].id = i;
        sort(my,my+m,cmp);
        kelusikaer();
        num = 0;
        dfsFirst(1,0,1);
        dfsSecond(1,1);
        Build(1,n,1);
        for(int i = 1;i<=num-1;++i){
            if(dep[you[i].from] > dep[you[i].to]) swap(you[i].from,you[i].to);
            UpdatePoint(you[i].val,newid[you[i].to],1);
        }
        sort(my,my+m,cmp2);
        for(int i = 0;i<m; ++i){
            int x = my[i].form;
            int y = my[i].to;
            if(my[i].ischoosen){
                printf("Ohyee\n");
            }else{
                printf("%d\n",Find_MIN(x,y));
            }
        }

    }
    return 0;
}

T2

水,一开始还想直接用int读?,我真天真。

#include <bits/stdc++.h>
#define nmax 1000000
#define ll long long
using namespace std;
char str[nmax];
void convertToNum(int tag1,int tag2,int & ans){
    int base = 1;
    ans = 0;
    for(int i = tag2;i>=tag1;i--){
        ans += (str[i] -'0') *base;
        base*=10;
    }
}
int main()
{
    int a,b,c;
    char op,equ;
    ll ans;
    while(scanf("%s",str) != EOF){
        int len = strlen(str);
        int tag1 ,tag2,tag3,tag4,tag5;
        tag1 = 0;
        int type = 0;
        bool opisfound = false;
        bool equuisfound = false;
        for(int i= 0;i<len;++i){
            if(str[i] == '+' || str[i] == '-'){
                op = str[i];
                tag2 = i-1;
                tag3 = i+1;
                opisfound = true;
            }else if(str[i] == '='){
                tag4 = i-1;
                tag5 = i+1;
                equuisfound = true;
            }
            if(str[i] == '?'){
                if(!opisfound && !equuisfound) type = 1;
                else if(opisfound && !equuisfound ) type = 2;
                else type = 3;
            }
        }
        if(type == 1){
            convertToNum(tag3,tag4,b);
            convertToNum(tag5,len-1,c);
            if(op == '+') ans = c - b;
            else ans = b+c;

        }else if(type == 2){
            convertToNum(tag1,tag2,a);
            convertToNum(tag5,len-1,c);
            if(op == '+') ans = c- a;
            else ans = a- c;

        }else{
            convertToNum(tag1,tag2,a);
            convertToNum(tag3,tag4,b);
            if(op == '+') ans = a+b;
            else ans = a-b;
        }
        printf("%lld\n",ans);

    }
    return 0;
}

T3

贪心水,错了几发贡献罚时。

#include <bits/stdc++.h>
#define nmax 5050
#define ll long long
using namespace std;
int n;
ll total;
struct ite{
    ll price;
    ll num;
}item[nmax];

bool cmp(ite a, ite b){
    if(a.price < b.price) return true;
    else return false;
}
int main()
{
    while(scanf("%lld %d",&total,&n) != EOF){
        for(int i = 0;i<n;++i){
            scanf("%lld %lld",&item[i].price,&item[i].num);
        }
        sort(item,item+n,cmp);
        ll ans = 0;
        for(int i = 0;i<n;++i){
            if(total >= item[i].num){
                ans += item[i].num * item[i].price;
                total -= item[i].num;
                if(total == 0) break;
            }else{
                ans += total * item[i].price;
                total = 0;
                break;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

T4

手推Fib数列,然后秒。

#include <bits/stdc++.h>
#define nmax 1000100
#define MOD 1000000007
using namespace std;
int a[nmax];
void init(){
    a[1] = 1;
    a[2] = 2;
    a[3] = 3;
    for(int i = 4;i<=1000000;++i){
        a[i] = (a[i-1] + a[i-2]) % MOD;
    }
}
int main()
{
    int n;
    init();
    while(scanf("%d",&n) != EOF){
        printf("%d\n",a[n]);
    }
    return 0;
}

T5

树上骚操作,发现能贡献答案的也就2种结构,维护每个节点SIZE即可,写完调了一会就出来,也是没时间写了。

#include <bits/stdc++.h>
#define ll long long
#define nmax 200820
using namespace std;
int fa[nmax],son[nmax],sz[nmax],newid[nmax],dep[nmax],newout[nmax],newid2[nmax];
int num,tot,head[nmax];
int minu[nmax];
struct edge{
    int to;
    int next;
}edg[nmax<<2];
struct tre{
    int l,r;
    ll val,lazy;
    int mid(){
        return (l+r)>>1;
    }
}tree[nmax<<2];
void add(int u, int v){
    edg[tot].to = v;
    edg[tot].next = head[u];
    head[u] = tot++;
}
void dfsFirst(int rt, int f,int d){
    dep[rt] = d;
    fa[rt] = f;
    sz[rt] = 1;
    for(int i = head[rt]; i!= -1; i = edg[i].next){
        int nxt = edg[i].to;
        if(nxt != f){
            dfsFirst(nxt,rt,d+1);
            sz[rt]+=sz[nxt];
            if(son[rt] == -1 || sz[nxt] > sz[son[rt]]){
                son[rt] = nxt;
            }
        }
    }
}
void dfsSecond(int rt, int tp){
    newid[rt] = ++num;
    if(son[rt] == -1){
        newid2[rt] = num;
        return;
    }
    dfsSecond(son[rt],tp);
    for(int i = head[rt];i != -1; i = edg[i].next){
        int nxt = edg[i].to;
        if(nxt != son[rt] && nxt != fa[rt])
            dfsSecond(nxt,nxt);
    }
    newid2[rt] = num;
}
void init(){
    memset(head,-1,sizeof head);
    memset(son,-1,sizeof son);
    tot = num = 0;
}
int ans = 0;
void dfs(int rt,int f){
    if(sz[rt] == 2){
        minu[rt] = sz[rt];
        ans++;return;
    }else if(sz[rt] >= 3){
        int times = sz[rt] - 1;
        for(int i = head[rt]; i!= -1; i = edg[i].next){
            int nxt = edg[i].to;
            if(nxt != f && sz[nxt] == 1){
                times--;
            }
        }
        if(times == 0){
            ans++;
            minu[rt] = sz[rt];
            return;
        }
    }
    for(int i = head[rt]; i!= -1; i = edg[i].next){
        int nxt = edg[i].to;
        if(nxt != f && sz[nxt] >=2){
            dfs(nxt,rt);
            minu[rt] += minu[nxt];
        }
    }
    sz[rt] -= minu[rt];
    if(sz[rt] == 2){
        minu[rt] += sz[rt];
        ans++;
    }else if(sz[rt] >= 3){
        int i = head[rt];
        int nxt = edg[i].to;
        int ip = edg[i].next;
        int nxtp = edg[ip].to;
        if( (nxt!=f && nxt !=-1) && (nxtp !=f && nxtp != -1)){
            ans++;
            minu[rt] += sz[rt];
        }
    }
}
int n,m;
int main()
{
    while(scanf("%d",&n)!=EOF){
        init();
        int u,v,x,y;
        for(int i =1;i<=n-1;++i){
            scanf("%d %d",&u,&v);
            add(u,v);
            add(v,u);
        }
        dfsFirst(1,0,1);
        dfsSecond(1,1);
        dfs(1,0);
        printf("%d\n",ans);

    }
    return 0;
}

T6

QAQ

T7

本场比赛最坑的题没有之一,板子上面的判断有问题,我一直以为是算法有问题。其实就是一个高精度进制转换,T到心态爆炸。

比赛有风险啊。

#include<bits/stdc++.h>
#define nmax 80000000
using namespace std;
int ans[nmax];
char str[nmax];
char temp[nmax];
int pos = 0;
void div(int b)
{
    int d=0;
    int len = strlen(str);
    int temppos= 0;
    while(strcmp(str,"0")!=0){
        d = 0;
        temppos = 0;
        for(int i=0;i<len;i++){
                temp[temppos++]=(d*10+str[i]-'0')/b+'0';
                d=(d*10+(str[i]-'0'))%b;
        }
        ans[pos++] = d;
        int p=0;
        for(int i=0;i<temppos;i++)
            if(temp[i]!='0') {p=i;break;}
        temp[temppos] = '\0';
       strcpy(str,temp+p);

       len = temppos-p;
       if(str[0] == '0' || str[0] == '\0') break;
    }
}
int main()
{
    int b;
    while(scanf("%s",str) != EOF){
        scanf("%d",&b);pos = 0;div(b);
        for(int i = pos-1;i>=0;--i) printf("%d\n",ans[i]);
    }
    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、资源1项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值