AtCoder Regular Contest 108
Contest Link Official Editorial
A - Sum and Product
Given are integers \(S\) and \(P\) . Is there a pair of positive integers \((N,M)\) such that \(N+M=S\) and \(N×M=P\) ?
Solution
签到题。 \(1e9\) 不能直接枚举,那么就枚举 \(P\) 较小的约数即可。
Code
//Author: RingweEH
S=read(); P=read(); ll lim=sqrt(P);
for ( ll i=1; i<=lim; i++ )
{
if ( P%i ) continue;
ll j=P/i;
if ( (i+j)==S ) { printf( "Yes\n" ); return 0; }
}
printf( "No\n" );
B - Abbreviate Fox
Given is a string \(S\) of length \(N\) consisting of lowercase English letters. Snuke can do this operation any number of times: remove fox
occurring as a substring from \(s\) and concatenate the remaining parts of \(s\) .
What is the minimum possible length of \(s\) after some number of operations by Snuke?
Solution
我是乱搞过的……不知道 WA+TLE
了多少发。具体就是由于新出现的 fox
只能在删掉的地方,所以考虑每次删掉一个就把两边的搞一遍。
然后再加了个暴力捡漏??
正解:令 \(t\) 初始为一个空串,然后重复下面的步骤直到 \(s\) 为空串:
- 把 \(s\) 的第一个字符移动到 \(t\) 的末尾,如果 \(t\) 的末尾出现
fox
那么删除掉并计入答案。
妙啊。
Code
//Author: RingweEH
//乱搞代码
int check( int pos )
{
if ( s[pos]=='f' ) return 1;
if ( s[pos]=='o' ) return 2;
if ( s[pos]=='x' ) return 3;
return 0;
}
int repos( int l,int r )
{
while ( 1 )
{
if ( l<0 || r>=n ) return r;
if ( vis[l] || vis[r] ) return r;
int cl=check(l),cr=check(r);
if ( !cl || !cr ) return r;
if ( (cl!=2) && (cr!=2) ) return r;
if ( (cl==2) && (cr==2) ) return r;
if ( cl==2 )
{
if ( (l==0) || vis[l-1] ) return r;
l--; cl=check(l);
if ( cl!=1 ) return r;
if ( cr!=3 ) return r;
cnt++; vis[l]=1; vis[l+1]=1; vis[r]=1; l--; r++;
}
if ( cr==2 )
{
if ( (r>=(n-1)) || vis[r+1] ) return r;
r++; cr=check(r);
if ( cr!=3 ) return r-1;
if ( cl!=1 ) return r-1;
cnt++; vis[l]=1; vis[r-1]=1; vis[r]=1; l--; r++;
}
}
}
int main()
{
n=read(); cin>>s; //scanf( "%s",s );
memset( vis,0,sizeof(vis) );
for ( int i=0; i<n-2; i++ )
{
if ( vis[i] ) continue;
if ( (s[i]=='f') && (s[i+1]=='o') && (s[i+2]=='x') )
{
cnt++; vis[i]=1; vis[i+1]=1; vis[i+2]=1; i=repos( i-1,i+3 )-1;
}
}
string s2="";
for ( int i=0; i<n; i++ )
if ( !vis[i] ) s2=s2+s[i];
while( s2.find("fox")!=-1 )
{
s2.erase( s2.find("fox"),3 ); n -= 3;
}
printf( "%d",n-cnt*3 );
}
C - Keep Graph Connected
Given is an undirected connected graph with \(N\) vertices numbered 11 to \(N\), and \(M\) edges numbered \(1\) to \(M\) . The given graph may contain multi-edges but not self loops.
Each edge has an integer label between \(1\) and \(N\) (inclusive). Edge \(i\) has a label \(c_i\) , and it connects Vertex \(u_i\) and \(v_i\) bidirectionally.
Snuke will write an integer between \(1\) and \(N\) (inclusive) on each vertex (multiple vertices may have the same integer written on them) and then keep only the edges satisfying the condition below, removing the other edges.
Condition: Let \(x\) and \(y\) be the integers written on the vertices that are the endpoints of the edge. Exactly one of \(x\) and \(y\) equals the label of the edge.
We call a way of writing integers on the vertices good if (and only if) the graph is still connected after removing the edges not satisfying the condition above. Determine whether a good way of writing integers exists, and present one such way if it exists.
Solution
先在图上求一棵生成树,然后构造。如果不存在生成树就无解。
设点 \(1\) 为根,任意涂色,然后向下 \(\text{dfs}\) 。对于一条边 \((u,v,w)\) ,如果 \(tag[x]==w\) 那么给 \(v\) 任意涂色,否则 \(tag[v]=w\) ,这样即可构造出合法解。
Code
为什么把 add( read(),read(),read() )
改成 u=read(),v=read(),w=read(),add( u,v,w );
就 Accepted 了啊……没明白诶。
哦,它是函数啊,那没事了。
//Author: RingweEH
void dfs( int u )
{
for ( int i=head[u]; i; i=e[i].nxt )
{
int v=e[i].to;
if ( !tag[v] )
{
if ( tag[u]==e[i].val ) tag[v]= ( tag[u]==1 ) ? 2 : 1;
else tag[v]=e[i].val;
dfs( v );
}
}
}
D - AB
Given are an integer \(N\) and four characters \(cAA\) , \(cAB\) , \(cBA\) and \(cBB\) . Here, it is guaranteed that each of those four characters is A
or B
.
Snuke has a string \(s\) , which is initially AB
.
Let \(|s|\) denote the length of \(s\). Snuke can do the four kinds of operations below zero or more times in any order:
- Choose \(i\) such that \(1≤i<|s|\) , \(s_i\) =
A
, \(s_{i+1}\) =A
and insert \(cAA\) between the \(i\)-th and \((i+1)\)-th characters of \(s\) . - Choose \(i\) such that \(1≤i<|s|\) , \(s_i\) =
A
, \(s_{i+1}\) =B
and insert \(cAB\) between the \(i\)-th and \((i+1)\)-th characters of \(s\). - Choose \(i\) such that \(1≤i<|s|\) , \(s_i\) =
B
, \(s_{i+1}\) =A
and insert \(cBA\) between the \(i\)-th and \((i+1)\)-th characters of \(s\). - Choose \(i\) such that \(1≤i<|s|\) , \(s_i\) =
B
, \(s_{i+1}\) =B
and insert \(cBB\) between the \(i\)-th and \((i+1)\)-th characters of \(s\).
Find the number, modulo \((10^9+7)\) , of strings that can be \(s\) when Snuke has done the operations so that the length of \(s\) becomes \(N\) .
Solution
发现只有 4 种变化,一共16种情况。可以大力分讨一下。
- \(cAB=A,cAA=A\) ,最终答案一定是 \(AAAAA...B\) ,答案就是1.
- \(cAB=A,cAA=B,cBA=A\) ,发现:开头是 \(A\) ,结尾是 \(AB\) ,没有连续的 \(B\) . 那么就是 \(A....AB\) ,中间是不含连续 \(0\) 的 \(01\) 串,就是斐波那契数列的 \(n-2\) 项。
- \(cAB=A,cAA=B,cBA=B\) ,发现开头是 \(A\) ,结尾是 \(BB\) ,答案就是 \(2^{n-3}\) .
- \(cAB=B,cBB=B\) ,答案一定是 \(ABB...B\) ,为 1.
- \(cAB=B,cBB=A,cBA=A\) ,答案是 \(2^{n-3}\) .
- \(cAB=B,cBB=A,cBA=B\) ,答案是 \(fib(n-2)\)
Code
//Author: RingweEH
void power()
{
int b=n-3,res=1;
for ( int i=1; i<=b; i++ )
res=res*2%mod;
printf( "%d\n",res );
}
void fib()
{
int b=n-3,a1=1,a2=1;
for ( int i=1; i<=b; i++ )
{
int tmp=(a1+a2)%mod;
a1=a2; a2=tmp;
}
printf( "%d\n",a2 );
}
E - Random IS
There are \(N\) isu - chairs in Japanese - arranged from left to right. The \(i\)-th chair from the left has the ID number \(a_i\) . Here, it is guaranteed that \(a_i\) are distinct.
Snuke has decided to mark some of the chairs and throw away the rest. Initially, no chair is marked. We call a choice of marked chairs good when the IDs of the marked chairs are monotonically increasing from left to right.
Snuke has decided to do the following procedure to mark chairs:
- We say a chair \(x\) to be nice if (and only if) the choice of marked chairs is still good when \(x\) gets marked. Let \(k\) be the current number of nice chairs.
- If \(k=0\) , remove the unmarked chairs and terminate the procedure. Otherwise, choose one from the \(k\) nice chairs with equal probability, mark it, and go back to Step 1.
It can be proved that the expected value of the number of chairs that remain at the end of the procedure is a rational number. Let this value be \(P/Q\) , an irreducible fraction. Additionally, let \(M=10^9+7\) . Then, we can prove that there uniquely exists an integer \(R\) between \(0\) and \(M−1\) (inclusive) such that \(P≡Q×R(modM)\) , and that value equals \(P×Q−1(modM)\) , where \(Q−1\) is the modular multiplicative inverse of \(Q\). Find \(R\) .
定义大小为 \(n\) 的排列 \(a\) 的一个子序列 \(b\) 是好的当且仅当 \(b\) 递增,对于 \(a\) 的子序列 \(b\) 而言,定义一个数 \(i\) 是好的当且仅当 \(a_i\) 加入 \(b\) 后 \(b\) 仍然递增,现在给定 \(n\) 和排列 \(a\) ,你有一个 \(a\) 的子序列 \(b\) ,初始为空,每次操作你会在所有好的数中选择等概率随机一个好的数 \(i\) 并将 \(a_i\) 加入 \(b\) ,询问期望操作次数。
\(1≤n≤2000\) 。
Solution
一开始根本没看懂题
首先在两边补充两个点 \(a_0=0,a_{n+1}=n+1\) .
令 \(f[i][j]\) 表示只考虑 \((i,j)\) 的元素且钦定选了 \(a[i],a[j]\) 的期望个数。那么答案就就是 \(f[0][n+1]\) .
考虑枚举中间第一次选了 \(a[k](a[i]<a[k]<a[j])\) .
显然,易知两边的区间是独立的,期望值可以直接相加,那么有:
\]
其中 \(cnt\) 为满足 \(a[i]<a[k]<a[j]\) 的 \(k\) 的个数。特殊地,如果 \(cnt=0\) 那么 \(f[i][j]=0\) .
由此,我们可以分别考虑 \(\sum_kf[i][k]\) 和 \(\sum_kf[k][j]\) .发现这个东西其实是对称的,那么就只需要计算对于每个 \((i,j)\) ,满足 \(a[k]<a[j]\) 的 \(f[i][k]\) 之和即可。用树状数组维护。对 \(cnt\) 的计算可以使用二维前缀和。
时间复杂度 \(\mathcal{O}(N^2logN)\) .
Code
//Author: RingweEH
void add( int *arr,int pos,int val )
{
for ( ; pos<=n; pos+=lowbit(pos) )
arr[pos]=(arr[pos]+val)%mod;
}
int query( int *arr,int pos )
{
int res=0;
for ( ; pos; pos-=lowbit(pos) )
res=(res+arr[pos])%mod;
return res;
}
int main()
{
n=read();
for ( int i=1; i<=n; i++ )
{
for ( int j=1; j<=n; j++ )
s[i][j]=s[i-1][j];
a[i]=read();
for ( int j=a[i]; j<=n; j++ )
s[i][j]++;
}
inv[1]=1;
for ( int i=2; i<=n; i++ )
inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
a[0]=0; a[n+1]=n+1;
for ( int k=2; k<=n+2; k++ )
{
for ( int i=0; i+k<=n+1; i++ )
{
int j=i+k;
if ( a[i]>a[j] ) continue;
int cnt=s[j-1][a[j]-1]-s[j-1][a[i]]-s[i][a[j]-1]+s[i][a[i]];
if ( !cnt ) continue;
int val=((ll)(query(tr1[i],a[j]-1)+query(tr2[j],n-a[i]))*inv[cnt]+1)%mod;
if ( j<=n ) add( tr1[i],a[j],val );
if ( i>=1 ) add( tr2[j],n-a[i]+1,val );
if ( i==0 && j==n+1 ) printf( "%d\n",val );
}
}
}
F - Paint Tree
Given is a tree with \(N\) vertices numbered \(1\) to \(N\), and \(N−1\) edges numbered \(1\) to \(N−1\) . Edge \(i\) connects Vertex \(a_i\) and \(b_i\) bidirectionally and has a length of \(1\) .
Snuke will paint each vertex white or black. The niceness of a way of painting the graph is \(max(X,Y)\) , where \(X\) is the maximum among the distances between white vertices, and \(Y\) is the maximum among the distances between black vertices. Here, if there is no vertex of one color, we consider the maximum among the distances between vertices of that color to be \(0\) .
There are \(2^N\) ways of painting the graph. Compute the sum of the nicenesses of all those ways, modulo \((10^9+7)\) .
Solution
所以题意就是求所有染色方案下白色直径和黑色直径中较大值的和。
考虑一条直径,设两端为 \(u_1,u_2\) ,并钦定 \(u_1=black\) .
如果两点颜色相同则贡献为 \(dis[u_1][u_2]\times 2^{N-2}\) 。
如果不同,易知答案一定是 \(u_1,v\) 或者 \(u_2,v\) 之间的距离。( \(v\) 为任意点)
记 \(dis[i][0]\) 为 \(i\) 到 \(u_1\) 的距离,\(dis[i][1]\) 为 \(i\) 到 \(u_2\) 的距离。最终答案就是 \(\sum\max(dis[i][0],dis[i][1])\)
考虑枚举这个最大值,尝试求出 “存在多少方案所选的最大值不大于这个数”,记为 \(f[i]\) .
那么有
\]
如果存在某一对 \(dis[i][0],dis[i][1]\) 均大于 \(i\) ,那么 \(f[i]=0\) . 处理了这种特殊情况后,再令 \(g[i]=\max(dis[i][0],dis[i][1])\) ,有
\]
直接对 \(g\) 排序,然后扫一遍即可得到 \(f[i]\) .
最终答案等于
\]
其中 \(D\) 为直径长度。
Code
//Author: RingweEH
void dfs( ll u,ll fa )
{
dep[u]=dep[fa]+1;
for ( ll v : gg[u] )
if ( v!=fa ) dfs( v,u );
}
int main()
{
n=read();
for ( ll i=1,u,v; i<n; i++ )
u=read(),v=read(),gg[u].push_back(v),gg[v].push_back(u);
//---------------------beginning-------------------------
dep[0]=-1; dfs( 1,0 );
ll u1=-1,mx=0;
for ( ll i=1; i<=n; i++ )
if ( dep[i]>mx ) mx=dep[i],u1=i;
dfs( u1,0 );
for ( ll i=1; i<=n; i++ )
dis1[i]=dep[i];
ll u2=-1; mx=0;
for ( ll i=1; i<=n; i++ )
if ( dep[i]>mx ) mx=dep[i],u2=i;
dfs( u2,0 );
for ( ll i=1; i<=n; i++ )
dis2[i]=dep[i];
//------------------------diameter---------------------------
ll gcnt=0;
for ( ll i=1; i<=n; i++ )
if ( i!=u1 && i!=u2 ) g[++gcnt]=max( dis1[i],dis2[i] );
sort( g+1,g+1+gcnt ); ll lim=0;
for ( ll i=1; i<=n; i++ )
lim=max( lim,min(dis1[i],dis2[i]) );
//-----------------------get_g---------------------------------
for ( ll i=mx; i>=lim; i-- )
{
while ( gcnt>=1 && g[gcnt]>i ) gcnt--;
f[i]=power(2,gcnt);
}
//----------------------get_f----------------------------------
ll tmp=0,ans=0;
for ( ll i=lim; i<=mx; i++ )
{
f[i]=((f[i]-tmp)%mod+mod)%mod;
tmp=(tmp+f[i])%mod;
ans=(ans+f[i]*i)%mod;
}
ans=(ans+mx*power(2,n-2) )%mod;
//--------------------get_ans-----------------------------
printf( "%lld",ans*2%mod );
}
AtCoder Regular Contest 108的更多相关文章
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
- AtCoder Regular Contest 096
AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...
- AtCoder Regular Contest 097
AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...
随机推荐
- leetcode 30day--2
202. Happy Number Write an algorithm to determine if a number n is "happy". A happy number ...
- TCP回射客户服务器模型(01 socket bind listen accept connect)
socket函数(安装电话机)头文件:#include<sys/socket.h> int socket(int family, int type, int protocol); //返 ...
- WSL2:我在原生的Win10玩转Linux系统
原文地址:梁桂钊的博客 博客地址:http://blog.720ui.com 欢迎关注公众号:「服务端思维」.一群同频者,一起成长,一起精进,打破认知的局限性. WSL2:我在原生的Win10玩转Li ...
- linux帮助手册(help/man/info)
linux本身有数据库(数据库名whatis)--man实际是从whatis数据库里查找信息. makewhatis 刚装系统,若man不能用,用makewhatis命令.整理whatis数据库. 当 ...
- ceph与flashcache的around模式结合启动问题
问题 通过对我们的启动流程看了下,目前是穿到一个脚本里面的,然后这个脚本是用无限循环的方式去执行一些事情,这个地方不符合松耦合的设计,一个模块做一个事情,两个并不相关的功能不要嵌入另一个脚本,否则出现 ...
- PLSQL-解析XML
DECLARE v_xmlclob CLOB := '<?xml version="1.0" encoding="UTF-8"?> <head ...
- PHP弱类型漏洞学习
简介 PHP在使用双等号(==)判断的时候,不会严格检验传入的变量类型,同时在执行过程中可以将变量自由地进行转换类型.由于弱数据类型的特点,在使用双等号和一些函数时,会造成一定的安全隐患 eg: &l ...
- 一文带你读懂!华为云在ACMUG技术沙龙上都透露了些啥?
摘要:近日,华为云数据库业务总裁苏光牛在ACMUG中国MySQL用户组主办的 "华为云专场" 技术沙龙中分享了华为云数据库重磅新品GaussDB的核心能力与竞争优势.那么, Gau ...
- 企业级工作流解决方案(十五)--集成Abp和ng-alain--Abp其他改造
配置功能增强 Abp定义了各种配置接口,但是没有定义这些配置数据从哪里来,但是管理配置数据对于一个应用程序来说,是必不可少的一件事情. .net的配置数据管理,一般放在Web.config文件或者Ap ...
- httpservlet类中两个service方法
在浏览器访问html页面时,当数据提交给servlet时发生了什么,这是我们需要了解的. 1.我们需要了解一下servlet的继承体系. servlet接口 ------->GenericSer ...