首页 > 其他分享 >20230307模拟赛

20230307模拟赛

时间:2023-03-07 20:34:19浏览次数:38  
标签:20230307 int void pos tot ++ id 模拟

20230307

A

根据题面信息可知图为奇环树,考虑将环上的点和树上的点分开处理,预处理出来环上的点。

如果先去想如何处理树上的点,可以想到一种\(dp\)方法,设\(f_{i,0/1}\)表示当前点为\(i\),对于\(i\)向父亲连的边,值为\(w/1\)的一段在\(i\)上是否可行,对于每一个点开一个\(map\),用来存该点上所有值。

这一做法是正确的,但过于麻烦。

如果先考虑环,容易发现环上的边的方向全部相同,也就是说环上的点至少会有一个\(1\)和一个\(w_i\),那么连接他与他儿子的边的“\(1\)”一段应当在他的儿子上,这样其子树中所有边的方向都是确定的,那么我们枚剧环的方向,用\(map\)来存每一个点上的所有值,不冲突就输出所有边的方向,冲突就换另一种方向,仍冲突则无解,复杂度为\(O(nlogn)\)。

code:

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
struct edge{
    int v,w,id;
};
vector<edge> e[N];
int n;
int dfn[N],tim;
int loop[N],tot,on[N],pa[N];
edge pre[N],nxt[N],pl[N];
void get(int u){
    dfn[u]=++tim;
    for(auto i:e[u]){
        int v=i.v;
        if(v==pa[u]) continue;
        if(dfn[v]){
            if(dfn[v]<dfn[u]) continue;
            loop[++tot]=v;
            pre[tot]=i;
            pre[tot].v=u;
            on[v]=1;
            while(v!=u){
                loop[++tot]=pa[v];
                pre[tot]=pl[v];
                v=pa[v];
                on[v]=1;
            }
        } 
        else pa[v]=u,pl[v]=i,get(v);
    }
}
int ans[N];
map<int,int> mp[N];
bool boom;
void dfs(int u,int fa){
    for(auto i:e[u]){
        int v=i.v,w=i.w,id=i.id;
        if(on[v]||v==fa) continue;
        ans[id]=v;
        if(mp[u].find(w)!=mp[u].end()){
            boom=1;
            return;
        }
        mp[u][w]=1;
        dfs(v,u);
    }
}
int main(){
    freopen("match.in","r",stdin);
    freopen("match.out","w",stdout);
    scanf("%d",&n);
    int u,v,w;
    // bool _=0; 
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&u,&v,&w);
        // if(i==1&&n==2000&&u==1577) _=1;
        e[u].push_back({v,w,i});
        e[v].push_back({u,w,i});
    }
    get(1);
    for(int i=1;i<=tot;i++)
        nxt[i]=pre[i+1];
    nxt[tot]=pre[1];
    // if(_)
    //     printf("%d\n",tot);
    // for(int i=1;i<=tot;i++) printf("%d ",loop[i]);
    // printf("\n");
    // for(int i=1;i<=tot;i++) printf("%d %d %d\n",pre[i].v,pre[i].w,pre[i].id);
    loop[0]=loop[tot],loop[tot+1]=loop[1];
    for(int i=1;i<=tot;i++){
        mp[loop[i]].clear();
        ans[pre[i].id]=loop[i-1];
        mp[loop[i]][pre[i].w]=1;
        dfs(loop[i],0);
        if(boom) break;
    }
    if(!boom){
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);
        return 0;
    }
    // printf("?\n");
    for(int i=1;i<=n;i++) mp[i].clear();
    boom=0;
    for(int i=1;i<=tot;i++){
        mp[loop[i]].clear();
        ans[nxt[i].id]=loop[i+1];
        mp[loop[i]][nxt[i].w]=1;
        dfs(loop[i],0);
        if(boom) break;
    }
    if(!boom){
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);
        return 0;
    }
    printf("impossible\n");
}

B

\(30pts:\)直接维护两个存钱罐和所有的值,但\(multiset\)维护会\(TLE\)

\(100pts:\)每次插入点的时候更新贡献,记录每个\(x\)的最小\(y\),在线段树上二分;删除操作用线段树分治,可以旋转坐标系\((x,y)\)->\((x-y,y)/(y-x,x)\),在叶子节点上开\(multiset\),复杂度为\((nlogn)\).


code:

#include<bits/stdc++.h>
using namespace std;
const int N=2.5e5+5;
const int inf=0x3f3f3f3f;
int n,m=2.5e5;
int f[N<<4],g[N<<4][2],h[N<<4][2];
multiset<int> s[N<<2][2];
void pushup(int rt){
    f[rt]=min(f[rt<<1],f[rt<<1|1]);
    for(int i=0;i<2;i++){
        g[rt][i]=min(g[rt<<1][i],g[rt<<1|1][i]);
        h[rt][i]=min(h[rt<<1][i],h[rt<<1|1][i]);
        f[rt]=min(f[rt],g[rt<<1][i]+h[rt<<1|1][i^1]);
    }
}
void update(int rt,int l,int r,int k,int x,int y,int op){
    if(l==r){
        if(op==1) s[x+m][k].insert(y);
        else s[x+m][k].erase(s[x+m][k].find(y));
        if(s[x+m][k].empty()) g[rt][k]=h[rt][k]=inf;
        else {
            g[rt][k]=*s[x+m][k].begin();
            h[rt][k]=g[rt][k]+x;
        }
        if(h[rt][0]<inf&&h[rt][1]<inf) f[rt]=h[rt][0]+g[rt][1];
        else f[rt]=inf;
        return;
    }
    int mid=l+r>>1;
    if(x<=mid) update(rt<<1,l,mid,k,x,y,op);
    else update(rt<<1|1,mid+1,r,k,x,y,op);
    pushup(rt);
}
int main(){
    freopen("money.in","r",stdin);
    freopen("money.out","w",stdout);
    scanf("%d",&n);
    memset(f,0x3f,sizeof f);
    memset(g,0x3f,sizeof g);
    memset(h,0x3f,sizeof h);
    int op,k,x,y;
    while(n--){
        scanf("%d%d%d%d",&op,&k,&x,&y);
        k&=1;
        if(k) update(1,-m,m,k,x-y,y,op);
        else update(1,-m,m,k,y-x,x,op);
        printf("%d\n",f[1]<inf?f[1]:-1);
    }
    return 0;
}

C



code:

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int T;
int n,id,t,cnt,tot,a[N],pos[N],ans[N];
int vis[N];
vector<int> vec[N];
void dfs1(int u){
    if(!vis[u]){
        vis[u]=1;
        dfs1(u>>1);
        a[++tot]=u;
    }
    u|=(1<<t-1);
    if(!vis[u]){
        vis[u]=1;
        dfs1(u>>1);
        a[++tot]=u;
    }
}
void dfs2(int u){
    //printf("u:%d\n",u);
    vec[id].push_back(u);
    if(!vis[u]){
        vis[u]=1;
        dfs2(u>>1);
    }
    u|=(1<<t);
    if(!vis[u]){
        vis[u]=1;
        dfs2(u>>1);
    }
}
void solve(){
    memset(pos,0,sizeof pos);
    scanf("%d",&n);
    t=1;
    while((1<<t)<=n-t+1) ++t;
    --t;
    if(t<2){
        if(n==1) printf("0\n");
        if(n==2) printf("10\n");
        if(n==3) printf("101\n");
        if(n==4) printf("0010\n");
        return;
    }
    n-=(1<<t)+t-1;
    tot=0;
    memset(vis,0,sizeof vis);
    dfs1(0);
    reverse(a+1,a+tot+1);
    //printf("%d\n",tot);
    //for(int i=1;i<=tot;i++) printf("%d ",a[i]);
    //printf("\n");
    //printf("%d\n",n);
    if(!n) cnt=tot,memcpy(ans,a,sizeof a);
    else {
        memset(vis,0,sizeof vis);
        for(int i=1;i<=tot;i++)
            vis[(a[i%tot+1]<<1)|(a[i]&1)]=1;
        //printf("???%d\n",vis[0]);
        cnt=id=0;
        for(int i=1;i<=tot;i++){
            vec[++id].clear();
            dfs2(a[i]);
            vec[id].pop_back();
            //printf("%d\n",vec[id].size());
            if(vec[id].empty()){
                --id;
                continue;
            }
            if(vec[id].size()>=n){
                for(int j=i%tot+1;j!=i;j=j%tot+1){
                    if(pos[j])
                        for(int k:vec[pos[j]])
                            ans[++cnt]=k;
                    ans[++cnt]=a[j];
                }
                vec[id].push_back(a[i]);
                for(int j=0;j<=n;j++) ans[++cnt]=vec[id][j];
                break;
            }
            n-=vec[id].size(),pos[i]=id;
        }
    }
    //printf("%d %d\n",t,cnt);
    for(int i=1;i<cnt;i++)
        printf("%c",(ans[i]&1)+'0');
    for(int i=0;i<t;i++)
        printf("%c",((ans[cnt]>>i)&1)+'0');
    printf("\n");
    return;
}
int main(){
    freopen("tao.in","r",stdin);
    freopen("tao.out","w",stdout);
    scanf("%d",&T);
    while(T--) solve();
    return 0;
}

标签:20230307,int,void,pos,tot,++,id,模拟
From: https://www.cnblogs.com/overthesky/p/17189523.html

相关文章

  • qsort的模拟实现与思路
    这是一篇介绍qsort函数模拟实现的博客,包含每一步实现的思路,对MSDN中qsort的使用进行了详细介绍。在实现的过程中,也对涉及到的知识点进行了一些简单介绍。希望可以给同为计......
  • 项目实战总结《模拟gin写一个web框架gee》
    概述:gee框架使用了前缀树算法来匹配路由,实现了路由分组,继承了gin的上下文写法,封装了常用的jsion,html,string,实现了服务端渲染,用钩子函数实现了中间件。项目的难度偏入门......
  • UVA-210 并行程序模拟 题解答案代码 算法竞赛入门经典第二版
    ​​GitHub-jzplp/aoapc-UVA-Answer:算法竞赛入门经典例题和习题答案刘汝佳第二版​​注意:每次unlock后,只需要拿出一个在阻塞队列里面的程序放到等待队列的头部。因为......
  • UVA-822 客户中心模拟 题解答案代码 算法竞赛入门经典第二版
    ​​GitHub-jzplp/aoapc-UVA-Answer:算法竞赛入门经典例题和习题答案刘汝佳第二版​​AC代码这个题目的做法可能并不唯一,对于某些场景有不同的答案也能过。我的思路:是......
  • RT-Thread 模拟器 simulator 搭建 LVGL 的开发调试环境
    前言RT-Thread当前的版本:4.1.0,通过简单的配置就可以支持最新的LVGL图形库版本,LVGL图形库以软件包的方式加入工程LVGL可以认为是当前开源、免费的优秀GUI的图形库,对内存的......
  • 天梯赛练习题L2-041 插松枝(模拟/贪心)
    https://pintia.cn/problem-sets/994805046380707840/exam/problems/1518582268930473984L2-041插松枝题目意思:人造松枝加工场的工人需要将各种尺寸的塑料松针插到松......
  • 天梯赛练习题L2-042 老板的作息表(模拟)
    https://pintia.cn/problem-sets/994805046380707840/exam/problems/1518582383141380096题目大意:给定n个工作的时间段,每个时间段都在00:00:00到23:59:59这个范围内......
  • 省选模拟赛 3.4
    A注意到\(a[i]\)可以异或上任意多次\(a[1\toi-1]\),于是求出\(1\toi-1\)的线性基\(V\),能变成数的个数是\(2^{|V|}\)。评测记录//Sparkle#include<bits......
  • 基于纳维斯托克斯方程的流体模拟器 FluidS
    源码下载gitclonehttps://github.com/george-chou/QPoisson.gitDemo视频原理浅讲编译教程C++版Qt项目动态及静态编译统一教程......
  • 2023.02.17 模拟赛小结
    2023.02.17模拟赛小结目录2023.02.17模拟赛小结更好的阅读体验戳此进入赛时思路T1CodeT2CodeT3Code正解T1CodeT2UPD更好的阅读体验戳此进入赛时思路T1有一道类似的......