首页 > 其他分享 >9.5 上午 becoder 模拟赛总结 & 题解

9.5 上午 becoder 模拟赛总结 & 题解

时间:2024-09-05 16:19:26浏览次数:10  
标签:pre nxt int 题解 msk becoder 9.5 now dp

T1 文本编辑器

说实话,看到题目的第一瞬间,我还以为 gm 第一道就放了平衡树。

一道链表的模板题,当然愿意也可以用平衡树写,不多说了,直接放代码(100pts):

#define N 1000005
char s[N],t[N];
int now,pre[N],nxt[N];
int main(){
    scanf("%s%s",s+1,t+1);
    int n=strlen(s+1);
    for(int i=1;i<=n;i++){
        if(t[i-1]=='L')
            nxt[pre[now]]=i,nxt[i]=now,pre[i]=pre[now],pre[now]=i,now=i;
        else
            pre[nxt[now]]=i,nxt[i]=nxt[now],pre[i]=now,nxt[now]=i,now=i;
        pre[0]=nxt[0]=0;
    }
    while(pre[now])  now=pre[now];
    for(int i=1;i<=n;i++)  printf("%c",s[now]),now=nxt[now];
}

T2 便利店

因为所有边的边权都是 \(1\),所以我们的单源最短路就可以直接 \(O(m)\) 用广搜实现。

那题目就简单了,对于每个询问,先跑一次最短路,用一个 vector 存储每个点的最短路径可以从哪些点走过来,记为 \(pre\)。

然后就从终点 dfs 回去,将每个点的 \(pre\) 与它连边,这样我们连的所有边就都是最短路径上的了。

最后再从起点 dfs 一遍,求每个点的概率就行了,就典型的概率 DP,不做赘述。

时间复杂度 \(O(km)\),代码如下(100pts):

#define N 5005
bool vis[N];
queue<int> q;
double now[N],sum[N];
int n,m,k,num,d[N],rd[N];
vector<int> v[N],pre[N],nxt[N];
void bfs(int s){
    memset(d,0x3f,sizeof d),d[s]=0,q.push(s);
    while(!q.empty()){
        int x=q.front();q.pop();
        for(auto y:v[x]){
            if(d[y]==0x3f3f3f3f)  d[y]=d[x]+1,q.push(y);
            if(d[y]==d[x]+1)  pre[y].push_back(x);
        }
    }
}
void dfs1(int x){
    if(vis[x])  return;
    vis[x]=1;
    for(auto y:pre[x])  nxt[y].push_back(x),dfs1(y);
}
void dfs2(int x){
    for(auto y:nxt[x]){
        now[y]+=now[x]/nxt[x].size();
        if(++rd[y]==pre[y].size())  dfs2(y);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<=m;i++){
        scanf("%d%d",&x,&y),x++,y++;
        v[x].push_back(y),v[y].push_back(x);
    }
    scanf("%d",&k);
    for(int i=1,x,y;i<=k;i++){
        memset(vis,0,sizeof vis),memset(now,0,sizeof now);
        memset(rd,0,sizeof rd),scanf("%d%d",&x,&y);
        x++,y++,bfs(x),dfs1(y),now[x]=1,dfs2(x);
        for(int i=1;i<=n;i++)  pre[i].clear(),nxt[i].clear(),sum[i]+=now[i];
    }
    for(int i=1;i<=n;i++)  if(sum[i]>sum[num])  num=i;
    printf("%d\n",num-1);
}

T3 独立集

考虑状压 DP,设 \(dp_msk\) 表示 \(msk\) 的子集内独立集的数目,转移时从 \(msk\) 中任选一个元素 \(i\) 出来。

那么转移有两种情况:

第一种情况是 \(i\) 不在独立集中,那么 \(i\) 号点就不会影响其他的点,这个时候从 \(dp_{msk^(1<<i)}\) 转移过来。

第二种情况是 \(i\) 点在独立集中,这时就要求它的邻居都不在独立集中。

设 \(nei_i\) 表示 \(i\) 自己与邻居的集合,这个时候就从 \(dp_{msk^(msk \& nei_i)}\) 转移过来。

转移就是这样,代码如下(100pts):

#define LL long long
const LL mod=1e9+7;
int n,m,ans,nei[26],dp[1<<26];
int main(){
	scanf("%d%d",&n,&m),dp[0]=1;
	for(int i=0;i<n;i++)  nei[i]|=(1<<i);
	for(int i=1,x,y;i<=m;i++){
		scanf("%d%d",&x,&y);
		nei[x]|=(1<<y),nei[y]|=(1<<x);
	}
	for(int i=1;i<(1<<n);i++)
		for(int j=0;j<n;j++)
			if(i&(1<<j))
				{dp[i]=((LL)dp[i]+dp[i^(1<<j)]+dp[i^(i&nei[j])])%mod;break;}
	for(LL i=1,po=233;i<(1<<n);i++,po=po*233%mod)  ans=(ans+po*dp[i])%mod;
	printf("%d\n",(ans+1)%mod);
}

T4 粉刷匠

我的做法被卡了,等我过了再来写...

标签:pre,nxt,int,题解,msk,becoder,9.5,now,dp
From: https://www.cnblogs.com/tkdqmx/p/18398689

相关文章

  • 【转载】P1399 [NOI2013] 快餐店 题解
    作者%%%%%%NightTide%%%%%%题目大意求一棵基环树的重心。即一个点,使得树上到其距离最长的点到其的距离最短。注意,这个点不一定是一个节点,可以在树上的任意位置。输出树上到其距离最长的点到其的距离。或者说求基环树最短的直径?(大雾解题思路显然,这颗基环树的直径只有两......
  • [USACO13OPEN] Photo G 题解
    前言题目链接:洛谷。题意简述一个长度为\(n\)的序列,有一些位置染了色。现给出\(m\)条限制,第\(i\)条限制为\(l_i\simr_i\)中有且仅有一个位置染色。求出满足这\(m\)中条件,染色位置个数最多为多少。\(n\leq2\times10^5\),\(m\leq10^5\)。题目分析方法\(1\):差......
  • Baby Ehab Plays with Permutations 题解
    前言题目链接:Codeforces;洛谷。题意简述你有一个长度为\(n\)的序列\(p\)满足\(p_i=i\),你可以进行\(x\)次操作,每次操作找到两个不同的\(i,j\)并且交换\(p_i,p_j\),问最终有几个可能的序列。分别求出\(x=1,\ldots,k\)时的答案。\(1\len\le10^9\),\(1\lek\le......
  • Marbles 题解
    前言题目链接:Codeforces;洛谷。题意简述给定长度为\(n\)的序列\(a\),你可以交换相邻元素,请问最少交换多少次使得序列连续,即对于每种颜色,其在序列中出现的位置都是连续一段。\(m=\max\{a_i\}\leq20\),\(n\leq4\times10^5\)。题目分析对于“连续的序列”,不放看做......
  • [POI2014] RAJ-Rally 题解
    前言题目链接:Hydro&bzoj;黑暗爆炸;洛谷。题意简述DAG求删点后最长路的最小值。\(n\leq5\times10^5\),\(m\leq10^6\)。题目分析其实对于删点/边加查询最长/短路的套路是有的。比如:故乡的梦、桥。本题也类似。我们考虑,如果删除的边不在原来最长路上,那么删之后的......
  • CF1941场题解
    RudolfandtheTicket算法:枚举。题意简述:从\(a\)数组中和\(b\)数组中各选出一个数,使得它们的和不超过\(k\),求选法数量。考虑直接枚举每一种可能的搭配即可。Rudolfand121算法:贪心。题意简述:定义一次操作为,该位置上的数减去\(2\),其前一个和后一个位置(必须存在)上的数......
  • 2023 ICPC 合肥题解
    gymD.BalancedArray\(\star\)赛时做法枚举前缀维护合法的\(k\)感性上\(k\)越大需要满足的式子越少,只保留最大的\(\log\)个\(k\),可以通过std枚举\(k\),合法的\(l\)一定是一个左端点为\(2k+1\)的区间,二分右端点等式\(\forall1\lei\lel-2k,a_{i}+a_{i+2k}=2a......
  • Codeforces Round 971 (Div. 4) ABCD题详细题解(C++,Python)
    前言:    本文为CodeforcesRound971(Div.4)ABCD题的题解,包含C++,Python语言描述,觉得有帮助或者写的不错可以点个赞    比赛打了没一半突然unrated了就不是很想继续写了,早起写个题解    (之前的div3也没复盘,哎真菜)目录题A:题目大意和解题......
  • AtCoder Beginner Contest 369 题ABCD详细题解--包含解题思路和两种语言(C++,Python)
    前言:    本文为AtCoderBeginnerContest369题ABCD详细题解,包括题目大意,详细的解题思路和两种语言描述,觉的有帮助或者写的不错可以点个赞几天前的比赛拖的有点久了比赛题目连接:Tasks-AtCoderBeginnerContest369目录题A:题目大意和解题思路:代码(C++):......
  • 洛谷 B3645 数列前缀和 2 题解
    前缀知识:枚举,费马小定理,逆元,线性乘法逆元,线段树(?)。解法1:暴力如题。暴力枚举即可,30分。由于太简单,不给代码。解法2:前缀积+费马小定理+逆元由于涉及静态区间,可以想到前缀积。前缀积公式为\(q_r/q_{l-1}\),除法恰好可以用逆元来算。直接写即可。不会超时,因为时间为\(O(n\logp)\)......