这场说实话确实水(逃*1),表示差一点就AK了(逃*2),然而被卡两个特判的我\(ssfd\)...\(qwq\)

表示这是第一次发整场比赛的题解...还请各位大佬原谅我太蒻写的垃圾啊\(qwq\)...

难度:据出题人之一\(sqn\)小\((da)\)姐\((ge)\)姐\((ge)\)说大概是难度倒序排列...但是个人感觉其实都不难(逃*3)...所以差一点就AK了(逃*4)

\(A\) 数字权重

题目描述:设一个\(n\)位数的最高位为\(a_1\),最低位为\(a_n\),对于给定的\(n,k(1<n\leq10^{13},|k|\leq10^{13})\),求不含前导\(0\)且满足\((\sum_{i=2}^{n}(a_i-a_{i-1}))=k\)的\(n\)位数的个数,结果对\(10^9+7\)取模

题目本质:\(imone\):"**题啊"(逃*5)

思路:看一下式子就显然了(逃*6)...不就是\(a_n-a_1=k\)嘛(逃*7)

详解:显然题目条件给出的\(k\)只对\(a_n\)和\(a_1\)产生限制,对于\(a_i(i\in[2,n-1])\)没有任何影响,所以对于所有的\(a_i(i\in[2,n-1])\)都有\(10\)种可能的结果\((a_i\in[0,9])\),由于\(a_n=a_1+k,a_1\in[1,9],a_n\in[0,9]\),所以分为三类讨论

  • \(|k|\geq10:\)由于两数码的差不可能\(>9\),所以此时无解,输出\(0\)即可
  • \(0\leq k\leq9:\)此时\(a_n\in[0,9],a_1\in[-k,9-k]\cap[1,9]\) \(\because k\in[0,9]\) \(\therefore (-k)\in[-9,0],(9-k)\in[0,9]\) \(\therefore a_1\in[1,9-k]\)

    所以此时答案为\((9-k)\times 10^{n-2}\)
  • \(-9\leq k\leq-1:\)同理\(a_n\in[0,9],a_1\in[-k,9-k]\cap[1,9]\) \(\because k\in[-9,-1]\) \(\therefore (-k)\in[1,9],(9-k)\in[10,18]\) \(\therefore a_1\in[-k,9]\)

    所以此时答案为\((10+k)\times 10^{n-2}\)

\(AC\)代码:

#include<cstdio>//N189A
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib> using namespace std; const int MOD=1e9+7; long long n,k,ans=1; long long qpow(long long base,long long u){
long long rep=1;
while(u){
if(u&1){
rep*=base;
rep%=MOD;
}
base*=base;
base%=MOD;
u>>=1;
}
return rep%MOD;
} int main(){
scanf("%lld%lld",&n,&k);
if(k>9||k<-9){
printf("0\n");
return 0;
}
ans*=qpow(10,n-2);
if(k>=0){
ans*=(9-k);
ans%=MOD;
}
else{
ans*=(10+k);
ans%=MOD;
}
printf("%lld\n",ans);
return 0;
}

\(B\) 毒瘤\(xor\)

题目描述:对于给定的数列\(a_1,a_2,\dots,a_n\)和\(q\)次询问\([l,r]\)求一个数\(x\)满足\(0\leq x<2^{31}\)且\(\sum_{i=l}^{r}x\oplus a_i\)最大,\(\oplus\)表示异或操作

题目本质:把所有数按照二进制打出来找规律啊(逃*8)

思路:如果用样例按二进制位找规律不难发现可以预处理所有二进制位上\(1\)的个数的前缀和,对于每次询问求一次区间和,进而判断\(x\)的对应二进制位的\(01\)情况(口胡)

详解:考虑异或操作的实质可以知道,所求的\(x\)和所有的\(a_i(i\in[l,r])\)对应的二进制位相异的个数应当尽可能多,(因为出题人的原因一开始写的是求最小的\(x\)...所以后面就按照写的时候的思路讲...其实都无所谓...毕竟\(spj\)修好了)所以预处理所有的\(a_i(i\in[1,n])\)二进制位上\(1\)的个数的前缀和,用树状数组求区间和,显然,当对应二进制位上\(1\)的个数不少于\(0\)的个数时\(x\)的对应二进制位为\(0\),反之为\(1\),在此策略下所求的\(x\)为满足条件的最小解

\(AC\)代码:

#include<cstdio>//N189B
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define lowbit(x) x&-x using namespace std; const int N=1e5+5; int n,q,ql,qr,qlen,ans; int a[N],c[N][32],base[32]; void add(int u,int v){
while(u<=n){
c[u][v]++;
u+=lowbit(u);
}
} int sum(int u,int v){
int rep=0;
while(u){
rep+=c[u][v];
u-=lowbit(u);
}
return rep;
} void pre(){
for(int i=0;i<=30;i++){
base[i]=(1<<i);
}
} int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
pre();
for(int i=1;i<=n;i++){
for(int j=0;j<=30;j++){
if(a[i]&base[j]){
add(i,j);
}
}
}
scanf("%d",&q);
for(int i=1;i<=q;i++){
ans=2147483647;
scanf("%d%d",&ql,&qr);
qlen=(qr-ql+2)>>1;
for(int j=0;j<=30;j++){
if(sum(qr,j)-sum(ql-1,j)>=qlen){
ans-=base[j];
}
}
printf("%d\n",ans);
}
return 0;
}

\(C\) 硬币游戏

题目描述:给定一个整数\(n(n\leq10^6)\)和两个长度为\(2n\)的字符串\(s,t\)(只包含\(U,D\))分别对应\(clccle\)和\(sarlendy\)面前的硬币,从\(clccle\)开始取,每次只能取两个人之前都没取过的位置的硬币,如果所取硬币朝上\((U)\)的话记为\(1\),所取硬币朝下\((D)\)的话记为\(0\),这样\(n\)次后两个人就得到了长度为\(n\)的数字串,若\(clccle\)的数字串大输出\(clccle\ trl!\),若\(sarlendy\)的数字串大输出\(sarlendy\ tql!\),若一样大输出\(orz\ sarlendy!\)

题目本质:贪心选\(U\)判断两个人最大能选取到的\(U\)的个数

思路:先选对应位置为\(U\ U\)的位置,然后选\(U\ D/D\ U\)(对应选取各自的\(U\)),剩下的\(D\ D\)可以直接忽略(对最终结果无影响),不过...如果\(clccle\)能取到的\(U\)比\(sarlendy\)少\(1\)个,\(clccle\)可以先手阻止\(sarlendy\)选\(U\)从而平局

详解:读入\(s,t\)后遍历\(1-2n\)对四种情况分别统计\(cnt\)可以分为以下几种情况

  • \(cnt_{U\ U}\)为奇数

    此时显然\(clccle\)能取到的\(U\)比\(sarlendy\)多\(1\)个

    • \(cnt_{U\ D}+1=cnt_{D\ U}||cnt_{U\ D}+2=cnt_{D\ U}\)

      此时两人能取到的\(U\)一样多
    • \(cnt_{U\ D}+1>cnt_{D\ U}\)

      此时\(clccle\)能取到的\(U\)多
    • \(cnt_{U\ D}+2<cnt_{D\ U}\)

      此时\(sarlendy\)能取到的\(U\)多
  • \(cnt_{U\ U}\)为偶数

    此时显然\(clccle\)能取到的\(U\)和\(sarlendy\)一样多

    • \(cnt_{U\ D}=cnt_{D\ U}||cnt_{U\ D}+1=cnt_{D\ U}\)

      此时两人能取到的\(U\)一样多
    • \(cnt_{U\ D}>cnt_{D\ U}\)

      此时\(clccle\)能取到的\(U\)多
    • \(cnt_{U\ D}+1<cnt_{D\ U}\)

      此时\(sarlendy\)能取到的\(U\)多

\(AC\)代码:

#include<cstdio>//N189C
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib> using namespace std; const int N=2e6+6; int n,cntuu,cntud,cntdu,cntdd; char s[N],t[N]; int main(){
scanf("%d",&n);
scanf("%s",s+1);
scanf("%s",t+1);
for(int i=1;i<=(n<<1);i++){
if(s[i]=='U'&&t[i]=='U'){
cntuu++;
continue;
}
if(s[i]=='U'&&t[i]=='D'){
cntud++;
continue;
}
if(s[i]=='D'&&t[i]=='U'){
cntdu++;
continue;
}
if(s[i]=='D'&&t[i]=='D'){
cntdd++;
continue;
}
}
if(cntuu&1){
if(cntdu==cntud+1||cntdu==cntud+2){
printf("orz sarlendy!\n");
return 0;
}
if(cntud+1>cntdu){
printf("clccle trl!\n");
return 0;
}
if(cntud+2<cntdu){
printf("sarlendy tql!\n");
return 0;
}
}
else{
if(cntdu==cntud||cntdu==cntud+1){
printf("orz sarlendy!\n");
return 0;
}
if(cntud>cntdu){
printf("clccle trl!\n");
return 0;
}
if(cntud+1<cntdu){
printf("sarlendy tql!\n");
return 0;
}
}
return 0;
}

\(D\) 粉樱花之恋

题目描述:不可描述的情节(逃*9)

题目本质:\(Fibonacci\)数列求和

思路:显然的线性递推当然要用矩阵加速啦\(qwq\)...所以...这题显然巨水(逃*10)...用\(dummyummy\)的话说:"粘个矩阵快速幂的板子不就行了吗"...

详解:考虑矩阵加速求\(Fibonacci\)数列的方法,用\(2\times 1\)的矩阵$$\begin{vmatrix}ans_0 \ ans_1 \end{vmatrix}$$存结果,以\(2\times 2\)的矩阵$$\begin{vmatrix}1&1\1&0\end{vmatrix}$$为底,有$$\begin{vmatrix}fib_{n-1}\fib_{n-2}\end{vmatrix}\times \begin{vmatrix}1&1\1&0\end{vmatrix}=\begin{vmatrix}fib_{n}\fib_{n-1}\end{vmatrix}$$类似地,我们可以推出\(Fibonacci\)数列求和的矩阵,相对于求\(Fibonacci\)数列,求和只是多了一个存\(sum\)的位置,于是可以用\(3\times 1\)的矩阵$$\begin{vmatrix}ans_0 \ ans_1 \ans_2\end{vmatrix}$$存结果,以\(3\times 3\)的矩阵$$\begin{vmatrix}1&1&1\0&1&1\0&1&0\end{vmatrix}$$为底,有$$\begin{vmatrix}sum_{n-1} \ fib_{n-1} \fib_{n-2}\end{vmatrix}\times \begin{vmatrix}1&1&1\0&1&1\0&1&0\end{vmatrix}=\begin{vmatrix}sum_{n-1}+(fib_{n-1}+fib_{n-2}) \ fib_{n-1}+fib_{n-2} \fib_{n-1}\end{vmatrix}$$因为\(fib_n=fib_{n-1}+fib_{n-2}\),所以 $$\begin{vmatrix}sum_{n-1} \ fib_{n-1} \fib_{n-2}\end{vmatrix}\times \begin{vmatrix}1&1&1\0&1&1\0&1&0\end{vmatrix}=\begin{vmatrix}sum_{n-1}+fib_n \ fib_n \fib_{n-1}\end{vmatrix}=\begin{vmatrix}sum_n \ fib_n \fib_{n-1}\end{vmatrix}$$在找到结果矩阵和基底矩阵之后,剩下的也就只有裸的矩阵快速幂了(是不是非常简单啊(逃*11))...因为初始化结果矩阵为$$\begin{vmatrix}sum_2=(fib_1+fib_2)\ fib_2 \fib_1\end{vmatrix}=\begin{vmatrix}2\1\1\end{vmatrix}$$所以在此还需要特判\(0(ans=1)\)和\(1(ans=2)\)的情况(表示挂在\(0\)上能哭死\(qwqwqwq\))

\(AC\)代码:

#include<cstdio>//N189D
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib> using namespace std; const int MOD=998244353; long long n; long long base[3][3],rep33[3][3],ans[3],rep13[3]; void pre(){
base[0][0]=1;
base[0][1]=1;
base[0][2]=1;
base[1][0]=0;
base[1][1]=1;
base[1][2]=1;
base[2][0]=0;
base[2][1]=1;
base[2][2]=0;
ans[0]=2;
ans[1]=1;
ans[2]=1;
} void mula(){
memset(rep13,0,sizeof rep13);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
rep13[i]+=base[i][j]*ans[j];
rep13[i]%=MOD;
}
}
for(int i=0;i<3;i++){
ans[i]=rep13[i];
}
} void mulb(){
memset(rep33,0,sizeof rep33);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
rep33[i][j]+=base[i][k]*base[k][j];
rep33[i][j]%=MOD;
}
}
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
base[i][j]=rep33[i][j];
}
}
} void qpow(long long u){
while(u){
if(u&1){
mula();
}
mulb();
u>>=1;
}
} int main(){
pre();
scanf("%lld",&n);
if(n==0){
printf("1\n");
return 0;
}
if(n==1){
printf("2\n");
return 0;
}
qpow(n-1);
printf("%lld\n",ans[0]);
return 0;
}

\(E\) 符合条件的整数

题目描述:求在\([2^n,2^m)(0\leq n<m\leq 65)\)上有多少个整数\(k\)满足\(k\equiv 1(mod\ 7)\)

题目本质:过于困(rui)难(zhi)的数学题

思路:直接算啊(逃*12)

详解:看到数据范围只有\(65\)显然可以\(O(n)\)跑暴力啊(逃*13),算出所有的区间\([1,2^i)\)上满足条件的\(k\)个数\(ans_i(i\in[0,65])\),对于询问\(n,m\)只需直接输出\(ans_m-ans_n\)即可,对于\(2^{65}\)会爆\(long\ long\)这件事,表示把除以\(7\)的商和余数分开存就不会爆,毕竟\(\frac{2^{65}}{7}\)并不会爆\(long\ long\)(其实...数据点根本就没卡满点...所以直接跑\(long\ long\)的也都过了\(qwq\))

\(AC\)代码:

#include<cstdio>//N189E
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib> using namespace std; int n,m; long long s[70],ys[70]; void pre(){
s[0]=0;ys[0]=1;
for(int i=1;i<=65;i++){
s[i]=s[i-1]<<1;
ys[i]=ys[i-1]<<1;
if(ys[i]>6){
s[i]+=ys[i]/7;
ys[i]%=7;
}
}
} long long solve(){
ys[n]+=5;
ys[m]+=5;
if(ys[n]>6){
s[n]+=ys[n]/7;
ys[n]%=7;
}
if(ys[m]>6){
s[m]+=ys[m]/7;
ys[m]%=7;
}
return s[m]-s[n];
} int main(){
scanf("%d%d",&n,&m);
pre();
printf("%lld\n",solve());
return 0;
}

\(F\) 可爱即正义

题目描述:交换字符串\(s\)中的两个字符\(s_i,s_j(i\neq j)\)使得\(s\)中不会出现\(suqingnianloveskirito\),如果不能实现输出\(No\),否则输出\(Yes\)并在第二行输出\(i,j\)

题目本质:字符串匹配

思路:看见数据范围之后暴力跑啊(逃*14)

详解:观察模式串\(suqingnianloveskirito\)不难发现根本没有前缀和后缀相同的部分,所以如果出现模式串一定是整串出现而不受前后字符影响并且随便改一下就行了(口胡)...又因为只能交换一次,所以当模式串出现次数\(t\geq3\)时显然输出\(No\),此时剩下的情况便只有\(t=0,1,2\)三种了

  • \(t=2:\)此时显然可以交换第一次出现的模式串的第一个字符和第二次出现的模式串的第二个字符,所以只需要知道两次出现时的位置即可
  • \(t=1:\)和\(t=2\)时类似,交换出现的模式串的第一位和第二位即可
  • \(t=0:\)看起来本来就没有还要再交换一次(sqn真(shi)可(zhen)爱(duo)...(逃*8))...这可交换哪两位好啊\(qwq\)...既然决定这么困难...那就交给\(rand()\)好了srand(prime with strlen()==8),为了保证交换之后的正确性还是再检验一下比较好

\(AC\)代码:

#include<cstdio>//N189F
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib> using namespace std; const int L=1e6+6; int len,lens=21,ap,poi,poii; char ch[L],s[24]={' ','s','u','q','i','n','g','n','i','a','n','l','o','v','e','s','k','i','r','i','t','o'}; bool check(int u){
for(int i=u,j=1;j<=21;i++,j++){
if(ch[i]!=s[j]){
return false;
}
}
return true;
} int main(){
srand(19260817);
scanf("%s",ch+1);
len=(int)strlen(ch+1);
if(len<21){
printf("Yes\n1 2\n");
return 0;
}
for(int i=1;i<=len-20;i++){
if(check(i)){
if(ap>1){
printf("No\n");
return 0;
}
if(ap==1){
ap++;
poii=i;
}
if(ap==0){
ap++;
poi=i;
}
}
}
if(ap==1){
printf("Yes\n");
printf("%d %d\n",poi,poi+1);
return 0;
}
if(ap==2){
printf("Yes\n");
printf("%d %d\n",poi,poii+1);
return 0;
}
while(1){
int u=(rand()*rand())%len+1,v=(rand()*rand())%len+1,flag=1;
if(u==v){
continue;
}
char jh=ch[u];
ch[u]=ch[v];
ch[v]=jh;
for(int i=1;i<=len-20;i++){
if(check(i)){
ch[v]=ch[u];
ch[u]=jh;
flag=0;
break;
}
}
if(flag){
printf("Yes\n");
printf("%d %d\n",u,v);
return 0;
}
}
return 0;
}

Nowcoder | [题解-N189]牛客OI赛制测试赛3的更多相关文章

  1. 【牛客OI赛制测试赛3】 毒瘤xor

    牛客OI赛制测试赛3 毒瘤xor 传送门 题面,水表者自重 Solution 前缀和简单题(挖坑待补) 代码实现 #include<stdio.h> #define int long lo ...

  2. 牛客OI赛制测试赛2(0906)

    牛客OI赛制测试赛2(0906) A :无序组数 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序意思就是(a,b)和(b,a) 算一组. 输入描述: ...

  3. 牛客OI赛制测试赛2

    A题: https://www.nowcoder.com/acm/contest/185/A 链接:https://www.nowcoder.com/acm/contest/185/A来源:牛客网 题 ...

  4. 8.30 牛客OI赛制测试赛1 F题 子序列

    题目描述 给出一个长度为n的序列,你需要计算出所有长度为k的子序列中,除最大最小数之外所有数的乘积相乘的结果 输入描述: 第一行一个整数T,表示数据组数.对于每组数据,第一行两个整数N,k,含义如题所 ...

  5. C数列下标 牛客OI赛制测试赛2

    链接:https://www.nowcoder.com/acm/contest/185/C来源:牛客网 给出一个数列 A,求出一个数列B. 其中Bi   表示 数列A中 Ai 右边第一个比 Ai 大的 ...

  6. 牛客OI赛制测试赛2 D 星光晚餐

    链接:https://www.nowcoder.com/acm/contest/185/D来源:牛客网 题目描述 Johnson和Nancy要在星光下吃晚餐.这是一件很浪漫的事情. 为了增加星光晚餐那 ...

  7. 牛客OI赛制测试赛2 C 数组下标

    链接:https://www.nowcoder.com/acm/contest/185/C来源:牛客网 题目描述 给出一个数列 A,求出一个数列B. 其中Bi   表示 数列A中 Ai 右边第一个比 ...

  8. 牛客OI赛制测试赛2 A 无序组数

    链接:https://www.nowcoder.com/acm/contest/185/A来源:牛客网 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序 ...

  9. 牛客OI赛制测试赛1 题解

    A 斐波那契 数竞生:这不是送分的常识吗? 这里引入一个叫卡西尼恒等式的玩意. 公式表达就是 设$fib[i]$为斐波那契数列的第$i$项$(i>0,i \in N_+)$ 则有 $fib[i+ ...

随机推荐

  1. python文件读和写

    fileHandle = open ( 'G:/qqfile/1.txt','w' )fileHandle.write('abcd')#写文件 地址要用反斜杠fileHandle.close() fi ...

  2. Git更新本地仓库

    1.查看远程仓库git remote -v2.从远程获取最新版本到本地git fetch origin master:temp3.比较本地的仓库与远程仓库的区别git diff temp4.合并tem ...

  3. py使用笔记-pandas函数

    1,nan替换为0df = df(np.nan, 0, regex=True)2.inf替换为0df= df(np.inf, 0.0, regex=True)3.从数据库读取数据到dataframei ...

  4. mysql uuid() 相同 重复

    mysql select UPPER(REPLACE(uuid(),'-','')) from xxxtable 得到相同的uuid的问题 - LWJdear的博客 - CSDN博客 https:// ...

  5. 理解ORM的前提:数据库中的范式和约束

    理解ORM的前提:数据库中的范式和约束 一.数据库中的范式: 范式, 英文名称是 Normal Form,它是英国人 E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出 ...

  6. macbookpro 以及 surface 的技术规格

    macbookpro 13.3 英寸 (对角线) LED 背光显示屏 (采用 IPS 技术):初始分辨率 x ( ppi),支持数百万色彩 15.4 英寸 (对角线) LED 背光显示屏 (采用 IP ...

  7. linux的一些基本命令

    一.linux的一些基本命令(使用的是CentOS7系统): 1.创建用户组,创建新用户并添加到用户组 添加用户,添加用户组命令: 增加用户:useradd -d /usr/username -m u ...

  8. github 操作

    https://www.cnblogs.com/cxk1995/p/5800196.html 1在已有的GitHub账号下创建项目. 2将GitHub项目克隆到本地.  git clone https ...

  9. python爬虫之win7Mongod安装使用

    1.下载地址:https://www.mongodb.com/download-center#community 下载完成以后下一步下一步安装. 安装路径 还需要建立一个数据库存储位置C:\mongo ...

  10. HashMap、HashTable、ConcurrentHashMap、HashSet区别 线程安全类

    HashMap专题:HashMap的实现原理--链表散列 HashTable专题:Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析 Hash,Tree数据结构时 ...