• 6.27 考试总结


    今天真是鬼畜的一场考试,考的是XJOI上的题目

    第三题看完题解至今仍是一脸懵逼,完全不懂如何实现

    (话说出题人是怎么想到把一个二维问题三维化的OwO

    算了算了,前两道题都是送分题,怪不得第三题这么难

    先说前两题的题解把

    首先第一题

    我们可以预处理约数个数函数可以O(1)算出某个b对某个f的贡献

    然后我们考虑后面的点的添加状态不会影响到前面的点的状态

    又发现当我们做到某个点的时候,由于b>0,所以这个点一定存在一种决策使得这个点对答案有贡献

    答案显然是所有的v的和,这样我们可以在O(nlogn)的时间内解决这个问题了

    不过貌似由于数据太难构造了,所以貌似随手写写随机化也可以过OwO

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
     
    typedef long long LL;
    const int maxn=200010;
    int n;
    int b[maxn],f[maxn],v[maxn];
    bool vis[maxn];
    LL r[maxn],g[maxn],ans;
     
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            for(int j=i;j<=n;j+=i)f[j]++;
        }
        for(int i=1;i<=n;++i)scanf("%d",&b[i]);
        for(int i=1;i<=n;++i)scanf("%lld",&r[i]);
        for(int i=1;i<=n;++i)scanf("%d",&v[i]),ans+=v[i];
        for(int i=1;i<=n;++i){
            if(g[i]==r[i]){
                vis[i]=true;
                for(int j=i;j<=n;j+=i)g[j]=g[j]+1LL*b[i]*f[j/i];
            }
        }
        printf("%lld
    ",ans);
        for(int i=1;i<=n;++i){
            if(vis[i])printf("1 ");
            else printf("0 ");
        }return 0;
    }
    

    第二题

    OwO 读完题之后发现是数据结构裸题

    离线之后按边权sort一遍做树链剖分用线段树维护一个类似连续子段和的东西就可以了

    写的时候一气呵成,直接就拍上了(话说这么裸的数据结构题目真的有写的必要么?

    实际上如果这道题目强制在线我们可以不用离线sort直接上主席树就可以了

    OwO

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
     
    const int maxn=100010;
    int n,m,u,v,w;
    int a[maxn];
    int dep[maxn],son[maxn],sz[maxn],fa[maxn];
    int pos[maxn],fp[maxn],top[maxn],tot=0;
    int Ans[maxn];
    int anc[maxn][20];
    int h[maxn],cnt=0;
    struct edge{
        int to,next;
    }G[maxn<<1];
    struct Edge{
        int u,v,w;
    }c[maxn];
    struct ASK{
        int x,y,lim,id;
    }Q[maxn];
    struct Seg_Tree{
        int pre,suf,val,len;
    }t[maxn<<2],tmp;
     
    bool cmpQ(const ASK &A,const ASK &B){return A.lim>B.lim;}
    bool cmpc(const Edge &A,const Edge &B){return A.w>B.w;}
    void add(int x,int y){
        ++cnt;G[cnt].to=y;G[cnt].next=h[x];h[x]=cnt;
    }
    void read(int &num){   
        num=0;char ch=getchar();
        while(ch<'!')ch=getchar();
        while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
    }
    void DFS(int u,int f){
        fa[u]=f;sz[u]=1;
        for(int i=h[u];i;i=G[i].next){
            if(G[i].to==f)continue;
            dep[G[i].to]=dep[u]+1;
            DFS(G[i].to,u);sz[u]+=sz[G[i].to];
            if(sz[G[i].to]>sz[son[u]])son[u]=G[i].to;
        }return;
    }
    void Get_pos(int u,int f){
        ++tot;pos[u]=tot;fp[tot]=u;top[u]=f;
        if(!son[u])return;
        Get_pos(son[u],f);
        for(int i=h[u];i;i=G[i].next){
            if(G[i].to==fa[u]||G[i].to==son[u])continue;
            Get_pos(G[i].to,G[i].to);
        }return;
    }
    void pre_LCA(){
        for(int i=1;i<=n;++i){
            anc[i][0]=fa[i];
            for(int j=1;(1<<j)<=n;++j)anc[i][j]=-1;
        }
        for(int j=1;(1<<j)<=n;++j){
            for(int i=1;i<=n;++i){
                if(anc[i][j-1]!=-1){
                    int a=anc[i][j-1];
                    anc[i][j]=anc[a][j-1];
                }
            }
        }return;
    }
    int LCA(int p,int q){
        int log;
        for(log=0;(1<<log)<=dep[p];++log);--log;
        for(int i=log;i>=0;--i){
            if(dep[p]-(1<<i)>=dep[q])p=anc[p][i];
        }
        if(p==q)return p;
        for(int i=log;i>=0;--i){
            if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i]){
                p=anc[p][i];q=anc[q][i];
            }
        }return fa[p];
    }
    int Get_Point(int u,int d){
        int log;
        for(log=0;(1<<log)<=dep[u];++log);--log;
        for(int i=log;i>=0;--i){
            if(anc[u][i]!=-1&&dep[anc[u][i]]>d)u=anc[u][i];
        }return u;
    }
    void build(int o,int L,int R){
        if(L==R){t[o].len=1;return;}
        int mid=(L+R)>>1;
        build(o<<1,L,mid);build(o<<1|1,mid+1,R);
        t[o].len=t[o<<1].len+t[o<<1|1].len;
    }
    Seg_Tree merge(const Seg_Tree &A,const Seg_Tree &B){
        tmp.len=A.len+B.len;
        tmp.pre=(A.pre!=A.len?A.pre:A.pre+B.pre);
        tmp.suf=(B.suf!=B.len?B.suf:B.suf+A.suf);
        tmp.val=A.val+B.val;
        tmp.val=tmp.val-a[A.suf]-a[B.pre]+a[A.suf+B.pre];
        return tmp;
    }
    void UPD(int o,int L,int R,int p){
        if(L==R){t[o].pre=t[o].suf=1;t[o].val=a[1];return;}
        int mid=(L+R)>>1;
        if(p<=mid)UPD(o<<1,L,mid,p);
        else UPD(o<<1|1,mid+1,R,p);
        t[o]=merge(t[o<<1],t[o<<1|1]);
    }
    Seg_Tree ask(int o,int L,int R,int x,int y){
        if(L>=x&&R<=y)return t[o];
        int mid=(L+R)>>1;
        if(y<=mid)return ask(o<<1,L,mid,x,y);
        else if(x>mid)return ask(o<<1|1,mid+1,R,x,y);
        else{
            Seg_Tree A=ask(o<<1,L,mid,x,y);
            Seg_Tree B=ask(o<<1|1,mid+1,R,x,y);
            return merge(A,B);
        }
    }
    Seg_Tree Get_ask(int u,int v){
        Seg_Tree cur;
        bool flag=true;
        while(top[u]!=top[v]){
            Seg_Tree now=ask(1,1,n,pos[top[u]],pos[u]);
            if(flag)cur=now,flag=false;
            else cur=merge(now,cur);
            u=fa[top[u]];
        }Seg_Tree now=ask(1,1,n,pos[v],pos[u]);
        if(flag)cur=now;
        else cur=merge(now,cur);
        return cur;
    }
    int Get_ans(int u,int v){
        if(dep[u]<dep[v])swap(u,v);
        if(u==v)return 0;
        int lca=LCA(u,v);
        if(v==lca){
            int tu=Get_Point(u,dep[v]);
            Seg_Tree A=Get_ask(u,tu);
            return A.val;
        }else{
            int tu=Get_Point(u,dep[lca]);
            int tv=Get_Point(v,dep[lca]);
            Seg_Tree A=Get_ask(u,tu);
            Seg_Tree B=Get_ask(v,tv);
            int ans=A.val+B.val;
            ans=ans-a[A.pre]-a[B.pre]+a[A.pre+B.pre];
            return ans;
        }
    }
     
    int main(){
        read(n);
        for(int i=1;i<n;++i)read(a[i]);
        for(int i=1;i<n;++i){
            read(u);read(v);read(w);
            u++;v++;
            add(u,v);add(v,u);
            c[i].u=u;c[i].v=v;c[i].w=w;
        }DFS(1,-1);Get_pos(1,1);pre_LCA();build(1,1,n);
        read(m);
        for(int i=1;i<=m;++i){
            read(Q[i].x);read(Q[i].y);read(Q[i].lim);Q[i].id=i;
            Q[i].x++;Q[i].y++;
        }
        for(int i=1;i<n;++i)if(dep[c[i].u]<dep[c[i].v])swap(c[i].u,c[i].v);
        sort(Q+1,Q+m+1,cmpQ);sort(c+1,c+n,cmpc);
        int now=1;
        for(int i=1;i<=m;++i){
            while(now<n&&c[now].w>Q[i].lim){
                UPD(1,1,n,pos[c[now].u]);
                now++;
            }
            Ans[Q[i].id]=Get_ans(Q[i].x,Q[i].y);
        }
        for(int i=1;i<=m;++i)printf("%d
    ",Ans[i]);
        return 0;
    }
    

    第三题上午更正题意没有听懂更正在说些什么OwO

    然后用最小圆覆盖乱写搞模拟退火然后爆零了

    后来下午弄懂了更正发现改了改原来模拟退火居然有20分

    (然而直接输出yes也有20分

    以为200分的挺多的,结果下午过来之后发现大家第一题都挂了OwO

    没错,是第一题都挂了。。

    我国果然是数据结构大国啊QAQ

    第二题AC人数远超第一题AC人数

    不过貌似这套题差不多跟NOI day1 难度相仿?

  • 相关阅读:
    String的本质是一个char*,只是以类的形式提供,使用起来比较方便
    感觉技术停滞时,该怎么办?(离开舒适区,刻意练习)
    网盘和云存储的区别(面向用户,产品形态,文件组织形式,功能侧重,一共4点区别)
    压力负载测试工具
    模型配置方式实现爬虫
    jquery Deferred
    Server是如何完成针对请求的监听、接收与响应1
    asp.net core 使用 Redis 和 Protobuf
    带进度条的文件上传
    ASP.NET Core Authorization
  • 原文地址:https://www.cnblogs.com/joyouth/p/5620548.html
Copyright © 2020-2023  润新知