Educational Codeforces Round 107 (Rated for Div. 2) 题解

文章目录

  • A. Review Site
  • B. GCD Length
  • C. Yet Another Card Deck
  • D. Min Cost String
  • E. Colorings and Dominoes
  • F. Chainword
  • G. Chips on a Board

Educational-Round-107

A. Review Site

都给了两台机子,直接把所有只会投②的扔到一台,其余的全是另一台

就是类型一和类型三的数量求和

#include <cstdio>
int T, n, ans;int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d", &n );ans = 0;for( int i = 1, x;i <= n;i ++ ) {scanf( "%d", &x );if( x == 2 ) continue;else ans ++;}printf( "%d\n", ans );}return 0;
}

B. GCD Length

直接强制gcd=10c−1gcd=10^{c-1}gcd=10c1,假设xxx的位数小于yyy的位数,则x=10a−1,y=10b−1+gcdx=10^{a-1},y=10^{b-1}+gcdx=10a1,y=10b1+gcd

加上gcdgcdgcd恰好保证了gcd(xgcd,ygcd)=1gcd(\frac{x}{gcd},\frac{y}{gcd})=1gcd(gcdx,gcdy)=1的性质

#include <cstdio>
#include <iostream>
using namespace std;
int T, n, a, b, c, A, B, C;int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x;x = x * x;y >>= 1;}return ans;
}int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d %d %d", &a, &b, &c );bool flag = 0;if( a > b ) swap( a, b ), flag = 1;A = qkpow( 10, a - 1 );C = qkpow( 10, c - 1 );B = qkpow( 10, b - 1 );if( flag ) printf( "%d %d\n", B + C, A );else printf( "%d %d\n", A, B + C );}return 0;
}

C. Yet Another Card Deck

真正有用的只有颜色第一次出现的位置

对于一个颜色第一次被操作,可以用树状数组统计该位置后面有多少颜色被操作过,那么最初其位置就会后移

对于多次被操作的颜色,因为颜色不超过五十种,显然可以暴力移动颜色

#include <cstdio>
#define maxn 300005
int n, Q, x;
int a[maxn], pos[maxn], vis[maxn], t[maxn], ans[maxn];int lowbit( int x ) {return x & ( -x );
}void add( int x ) {x = n - x + 1;for( int i = x;i <= n;i += lowbit( i ) )t[i] ++;
}int query( int x ) {x = n - x + 1; int ans = 0;for( int i = x;i;i -= lowbit( i ) )ans += t[i];return ans;
}int main() {scanf( "%d %d", &n, &Q );for( int i = 1;i <= n;i ++ ) {scanf( "%d", &a[i] );if( ! pos[a[i]] ) pos[a[i]] = i;}int cnt = 0;for( int i = 1;i <= Q;i ++ ) {scanf( "%d", &x );if( ! vis[x] ) {printf( "%d\n", pos[x] + query( pos[x] ) );cnt ++;for( int j = cnt;j > 1;j -- )ans[j] = ans[j - 1];ans[1] = x;add( pos[x] );vis[x] = 1;}else {for( int j = 1;j <= cnt;j ++ ) if( ans[j] == x ) {printf( "%d\n", j );for( int k = j;k > 1;k -- )ans[k] = ans[k - 1];ans[1] = x;break;}}}return 0;
}

D. Min Cost String

找规律a ab ac ad ae ...a[k] b bc bd be bf... b[k]...[k]

高级解释:剩余系(同余)

#include <cstdio>
#define maxn 200005
int n, k, cnt;
char s[maxn];int main() {scanf( "%d %d", &n, &k );for( int i = 0;i < k;i ++ ) {s[cnt ++] = i + 'a';for( int j = i + 1;j < k;j ++ )s[cnt ++] = i + 'a', s[cnt ++] = j + 'a';}int ip = 0;for( int i = 1;i <= n;i ++ )printf( "%c", s[ip % cnt] ), ip ++;return 0;
}

E. Colorings and Dominoes

利用概率论求解应该是更简单的,求出一张多米诺骨牌放在i,ji,ji,j位置的概率乘总方案数就是贡献

行多米诺骨牌只能用红色,列多米诺骨牌只能用蓝色

因此行列是彼此独立的,可以分开做,下面以行为例

考虑DPDPDP求概率,设dpi,0/1:idp_{i,0/1}:idpi,0/1:i 位置是一张多米诺骨牌的左边0/右边1

dpi,0=(dpi−1,1+12)×12dp_{i,0}=(dp_{i-1,1}+\frac{1}{2})\times \frac{1}{2}dpi,0=(dpi1,1+21)×2112\frac{1}{2}21是有可能i−1i-1i1是蓝色,天然隔绝一行中的两段,iii此时满足做左边的条件

dpi,1=dpi−1,0×12dp_{i,1}=dp_{i-1,0}\times \frac{1}{2}dpi,1=dpi1,0×21

12\frac{1}{2}21是表示iii为红色的概率

这个DPDPDP状态转移其实只与长度有关,因此只需要提取出一行中连续段长度即可

#include <cstdio>
#define int long long
#define mod 998244353
#define maxn 300000
int n, m, cnt;
char s[maxn];
int row[maxn + 5], col[maxn + 5];
int dp[maxn + 5][2];int id( int i, int j ) {return i * m + j;
}int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}signed main() {scanf( "%lld %lld", &n, &m );for( int i = 0;i < n;i ++ ) {scanf( "\n" );for( int j = 0;j < m;j ++ ) {scanf( "%c", &s[id( i, j )] );cnt += ( s[id( i, j )] == 'o' );}}int inv = qkpow( 2, mod - 2 ), All = qkpow( 2, cnt );dp[1][0] = inv; for( int i = 2;i <= maxn;i ++ ) {dp[i][0] = ( dp[i - 1][1] + inv ) * inv % mod;//还有可能是i-1为蓝色(概率为1/2)断开了行的两段dp[i][1] = dp[i - 1][0] * inv % mod;}int ans = 0;for( int i = 0;i < n;i ++ ) {for( int j = 0;j < m;j ++ ) {row[id( i, j )] = col[id( i, j )] = 1;if( i > 0 && s[id( i - 1, j )] == 'o' ) row[id( i, j )] = row[id( i - 1, j )] + 1;if( j > 0 && s[id( i, j - 1 )] == 'o' ) col[id( i, j )] = col[id( i, j - 1 )] + 1;if( s[id( i, j )] == 'o' ) ans = ( ans + dp[row[id( i, j )]][1] + dp[col[id( i, j )]][1] ) % mod;} }printf( "%lld\n", ans * All % mod );return 0;
}

F. Chainword

对单词建立trie

当在s的末尾增加一个字符的时候

相当于在 trie树上从一个结点u沿着一条转移边走到另外一个结点v

当然,也可以在某个字符串的结束位置不继续往下走,而是跳回到根节点

fi,u,v:f_{i,u,v}:fi,u,v: 表示sss加入了iii个字符,上方的线在trie的结点uuu上,下方的线在``trie的结点v`上 的方案数

发现这个DPDPDPiii没什么关系,可以使用矩阵快速幂优化

进行有效状态合并后才能转移不超时

  • SSSroot→uroot\rightarrow urootu的路径,TTTroot→vroot\rightarrow vrootv的路径,那么SSS一定是TTT的前缀/后缀
  • fi,u,v=fi,v,u⇒(u,v)(v,u)f_{i,u,v}=f_{i,v,u}\Rightarrow (u,v)(v,u)fi,u,v=fi,v,u(u,v)(v,u)可以视为一个状态

找到满足第一种要求的状态的点:从(0,0)(0,0)(0,0)开始bfsbfsbfs,每次转移的时候枚举最后一个字符,所有能访问到的结点

#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define int long long
#define mod 998244353
#define Pair pair < int, int >
queue < Pair > q;
map < Pair, int > mp;
int n, m;
char s[10];struct matrix {int v[170][170];matrix() {memset( v, 0, sizeof( v ) );}matrix operator * ( matrix &t ) const {matrix ans;for( int i = 0;i <= 160;i ++ )for( int j = 0;j <= 160;j ++ )for( int k = 0;k <= 160;k ++ )ans.v[i][j] = ( ans.v[i][j] + v[i][k] * t.v[k][j] % mod ) % mod;return ans;}
}O;matrix qkpow( matrix x, int y ) {matrix ans;for( int i = 0;i <= 160;i ++ )ans.v[i][i] = 1;while( y ) {if( y & 1 ) ans = ans * x;x = x * x;y >>= 1;}return ans;
}struct tree {int End, son[26];tree() {memset( son, -1, sizeof( son ) );}
}trie[170];int cnt;void insert() {int len = strlen( s + 1 ), now = 0;for( int i = 1;i <= len;i ++ ) {if( trie[now].son[s[i] - 'a'] == -1 )trie[now].son[s[i] - 'a'] = ++ cnt;now = trie[now].son[s[i] - 'a'];}trie[now].End = 1;
}int ID( int x, int y ) {if( x > y ) swap( x, y );if( ! mp.count( make_pair( x, y ) ) ) {mp[make_pair( x, y )] = mp.size();q.push( make_pair( x, y ) );}return mp[make_pair( x, y )];
}signed main() {scanf( "%lld %lld", &n, &m );for( int i = 1;i <= n;i ++ ) {scanf( "%s", s + 1 );insert();}mp[make_pair( 0, 0 )] = 0;q.push( make_pair( 0, 0 ) );while( ! q.empty() ) {Pair now = q.front(); q.pop();int id = ID( now.first, now.second );for( int i = 0;i < 26;i ++ ) {int x = trie[now.first].son[i], y = trie[now.second].son[i];if( x == -1 || y == -1 ) continue;O.v[id][ID( x, y )] ++;if( trie[x].End ) O.v[id][ID( 0, y )] ++;if( trie[y].End ) O.v[id][ID( x, 0 )] ++;if( trie[x].End && trie[y].End ) O.v[id][ID( 0, 0 )] ++;}}printf( "%lld\n", qkpow( O, m ).v[0][0] );return 0;
}

G. Chips on a Board

两人在玩Nim博弈游戏,有异或结论:在[l,r][l,r][l,r]范围内所有棋子到lll的距离的异或和

000则后手胜,不为000则先手胜

距离差在异或下的运算法则不好维护

考虑拆成二进制下每位独立维护

发现可以用倍增(倍增的本质就是二进制下每一位单独贡献)

dpi,j:[i,i+2j)dp_{i,j}:[i,i+2^j)dpi,j:[i,i+2j)区间内的棋子到iii的距离异或和

最高位的贡献是独立于所有比其小的贡献的

cnti:cnt_i:cnti:iii列的棋子个数

dpi,j=dpi,j−1⨁dpi+2j−1,j−1⨁[cnti+2j−1−cnti+2j−1−1mod2=1]2j−1dp_{i,j}=dp_{i,j-1}\bigoplus dp_{i+2^{j-1},j-1}\bigoplus [cnt_{i+2^j-1}-cnt_{i+2^{j-1}-1}\mod 2 =1]2^{j-1}dpi,j=dpi,j1dpi+2j1,j1[cnti+2j1cnti+2j11mod2=1]2j1

最后求答案异或和,也是枚举每位单独计算贡献

#include <cstdio>
#define maxn 200005
int n, m, Q;
int dp[maxn][20];
int bit[maxn], cnt[maxn];int main() {scanf( "%d %d", &n, &m );for( int i = 1, x;i <= n;i ++ )scanf( "%d", &x ), cnt[x] ++;for( int i = 1;i <= m;i ++ )cnt[i] += cnt[i - 1];bit[0] = -1;for( int i = 1;i <= m;i ++ )bit[i] = bit[i >> 1] + 1;for( int j = 1;j < 20;j ++ )for( int i = 1;i <= m;i ++ )if( i + ( 1 << j ) - 1 <= m )dp[i][j] = dp[i][j - 1] ^ dp[i + ( 1 << j - 1 )][j - 1] ^ ( ( ( cnt[i + ( 1 << j ) - 1] - cnt[i + ( 1 << j - 1 ) - 1] ) & 1 ) * ( 1 << j - 1 ) );scanf( "%d", &Q );while( Q -- ) {int ans = 0, l, r;scanf( "%d %d", &l, &r );for( int i = bit[m];~ i;i -- )if( l + ( 1 << i ) <= r ) {ans ^= dp[l][i];l += ( 1 << i );if( ( cnt[r] - cnt[l - 1] ) & 1 )ans ^= ( 1 << i );}printf( "%c", ans ? 'A' : 'B' );}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

李争——一个骨子里是极客的程序员

我的业余作品《IT 英雄传》&#xff0c;聚焦身边的英雄&#xff0c;以文字采访的形式记录奇人趣事&#xff0c;笑看风云变幻。所写的人都是我见过面且比较熟悉的&#xff0c;绝大部分都是交往很久的&#xff0c;其中为了避嫌&#xff0c;我很少写微软同事&#xff0c;但今天这一…

Pagodas HDU - 5512

Pagodas HDU - 5512 题意&#xff1a; 一开始给你两个数a和b&#xff0c;你可以得到c通过&#xff0c;cab&#xff0c;或者ca-b&#xff0c;你所能得到的数的范围是1~n&#xff0c;两个人轮流操作&#xff0c;当有一方无法操作时&#xff0c;另一方获胜 题解&#xff1a; c…

期望学习笔记

前言 突然发现自己没有系统学过期望。 做一本通的时候是从二分图开始听的课&#xff0c;dp这一章只是四处搜题解而已。 做期望题基本都是靠玄学和《感性理解》 都是很简单的东西&#xff0c;但系统很重要&#xff0c;该补的还是要补的。 期望的基本性质 E(c)cE(c)cE(c)cE(cx)…

仅此一文让你明白事务隔离级别、脏读、不可重复读、幻读

网络上关于这方面的博文有些偏理论&#xff0c;有些通篇代码&#xff0c;都不能深入浅出。本文用图文并茂的方式&#xff0c;配上行云流水般的代码&#xff0c;非要摆清楚这个问题。相关代码已提交至码云&#xff08;点击这里下载&#xff09;。事务是现代关系型数据库的核心之…

[AtCoder Regular Contest 123] 题解

文章目录A - Arithmetic SequenceB - Increasing TriplesC - 1, 2, 3 - DecompositionD - Inc, Dec - DecompositionE - TrainingF - Insert AdditionARC123A - Arithmetic Sequence 大讨论 只能111&#xff0c;先固定中间的数&#xff0c;看两边加谁&#xff0c;如果都是加负…

2.5:模拟总结

文章目录前言考场题目解析T1T2T3总结代码T1T2T3前言 50pts 30020 rnk19 … 把1000ms看成10s我也真是个人才。 T3自然溢出50带模数T成20有点离谱。 但倒没有因为WA失分。 就是菜罢了 考场 这次时间管理还是比较合理的。 乍看三题觉得T1似乎是个伞兵题 这离线下来可持久化数组…

Meeting HDU - 5521

Meeting HDU - 5521 题意&#xff1a; 一共有n个点&#xff0c;有m个块&#xff0c;每个块内有Si个点&#xff0c;块内点彼此到达费用为wi&#xff0c;两个人分别位于1和n号块&#xff0c;两者同时出发问最短时间遇到是多少&#xff1f;在哪些地方可以遇到&#xff1f; ΣSi&…

2.6模拟总结

前言 45pts 4500 rnk 34 写了200分&#xff0c;挂了155分 好哇&#xff01; 考场 这次状态还真是挺不错的。 开考&#xff0c;先看题。 T1期望&#xff0c;乍一看看不出来啥&#xff0c;似乎挺难的。 T2乍一看特别可做。 T3脑子里只有模拟退火 先去看T2。 被这种类似的题惯…

牛客IOI周赛26-提高组(逆序对,对序列,未曾设想的道路) 题解

文章目录逆序对对序列未曾设想的道路牛客IOI周赛26-提高组逆序对 这种套路之前已经见过几次了&#xff0c;肯定不是模拟操作数列 opt 1 对于i∈[1,l)⋃(r,n]i∈[1,l)\bigcup(r,n]i∈[1,l)⋃(r,n] 逆序对是不影响的 对于i∈(l,r)i∈(l,r)i∈(l,r) 与l/rl/rl/r的情况会反转&…

Frogs HDU - 5514

Frogs HDU - 5514 题意&#xff1a; 有n个青蛙&#xff0c;第 i 个青蛙每次只能够跳 ai​步&#xff0c;现在有m个石头围成一圈&#xff0c;编号为0到m−1&#xff0c;现在青蛙可以围着这个石头组成的圆跳无限次&#xff0c;每跳一次就会占领这个石头&#xff0c;可以无限占领…

Docker最全教程之树莓派和Docker(十六)

前言树莓派&#xff08;Raspberry Pi&#xff09;是一台卡片电脑&#xff08;只有信用卡大小&#xff09;&#xff0c;我们可以使用树莓派做很多事情&#xff0c;比如智能家居的中控、航空器、BT下载器、挖矿机、智能机器人、小型服务器&#xff08;花生壳网站&#xff09;等等…

Codeforces Round #724 (Div. 2) 题解

文章目录A. Omkar and Bad StoryB. Prinzessin der VerurteilungC. Diluc and KaeyaD. Omkar and MediansE. Omkar and ForestF. Omkar and Akmar#724-Div.2A. Omkar and Bad Story 直接set暴力加值&#xff0c;加满300300300个为止 #include <cstdio> #include <se…

2015沈阳区域赛

2015沈阳vj链接 题号题目知识点难度APattern StringBBazinga贪心签到题CMinimum Cut-CutDPagodas裴蜀定理签到题EEfficient TreeFFrogs欧拉函数银牌题GGame of Flying CircusHChessboardITriple二维线段树稳银快金JJohn’s FencesKKykneion asmaLNumber LinkMMeeting最短路&am…

模板:Prufer序列

所谓 Prufer 序列&#xff0c;就是 Prufer 发明的序列。 &#xff08;逃&#xff09; 前言 优雅的神奇魔术。 看名字很高大难&#xff0c;但实际上是高大清&#xff08;小清新&#xff09;。 很简单的建立起树与序列之间的双射&#xff0c;且这个序列的性质非常良好&#xff…

【NET CORE微服务一条龙应用】第三章 认证授权与动态权限配置

介绍系列目录&#xff1a;【NET CORE微服务一条龙应用】开始篇与目录在微服务的应用中&#xff0c;统一的认证授权是必不可少的组件&#xff0c;本文将介绍微服务中网关和子服务如何使用统一的权限认证主要介绍内容为&#xff1a;1、子服务如何实现和网关相同的鉴权方式2、接口…

Codeforces Round #725 (Div. 3) 题解

文章目录A. Stone GameB. Friends and CandiesC. Number of PairsD. Another Problem About Dividing NumbersE. Funny SubstringsF. Interesting FunctionG. Gift Set#725-Div.3A. Stone Game 先找到最大值最小值的位置&#xff0c;然后有三种选取&#xff08;两边中走一边/两…

I - Triple HDU - 5517

I - Triple HDU - 5517 题意&#xff1a; 由多重集A和多重集B&#xff0c;<a,b>∈A&#xff0c;<c,d,e>∈B&#xff0c;集合CA * B{<a,c,d>|<a,b>∈A&#xff0c;<c,d,e>∈B and be}。 现在需要你求出有多少个<a,c,d>满足&#xff1a;不…

模板:广义二项式反演/广义容斥(组合数学)

文章目录前言经典容斥原理广义二项式反演/广义容斥min-max 容斥所谓二项式反演&#xff0c;就是对两个项的式子进行反演。 &#xff08;逃&#xff09; 前言 期望和容斥是我的感性二兄弟&#xff01; 之前的容斥我基本也都是靠感性理解做的… 感性理解就会导致&#xff1a;考…

WebApiClient与Asp.net core DI的结合

1 WebApiClient一款基于HttpClient封装&#xff0c;只需要定义c#接口并修饰相关特性&#xff0c;即可异步调用远程http接口的客户端库WebApiClientWebApiClient.ExtensionsWebApiClient.Tools2 Http接口的注册与提供2.1 声明远程端http接口public interface IBaiduApi : IHttpA…

Codeforces Round #717 (Div. 2)

Codeforces Round #717 (Div. 2) CodeForces 1516 题号题目知识点ATit for Tat贪心BAGAGA XOOORRR思维题CBaby Ehab Partitions AgainDCutEBaby Ehab Plays with Permutations