博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #539 div1
阅读量:5907 次
发布时间:2019-06-19

本文共 6031 字,大约阅读时间需要 20 分钟。

1109A. Sasha and a Bit of Relax

记 $sum[i]$ 表示前 $i$ 位的异或和,当一个 $l,r$ 可以作为答案即 $sum[l]==sum[r]$ 并且 $l,r$ 同奇偶,所以我们可以记 $v[i][0/1]$ 表示前缀异或值为 $i$ 并且所在位置为奇/偶的方案数。每位答案为在我之前前缀异或值和我相同所在位置和我同奇偶的方案数。

效率 $O(n)$

 以下代码:

#include
#define il inline#define LL long long#define _(d) while(d(isdigit(ch=getchar())))using namespace std;const int N=3e5+5,M=2e6;LL ans;int n,a[N],v[M][2],sum;il int read(){ int x,f=1;char ch; _(!)ch=='-'?f=-1:f;x=ch^48; _()x=(x<<1)+(x<<3)+(ch^48); return f*x;}int main(){ n=read();v[0][0]++; for(int i=1;i<=n;i++){ a[i]=read();sum^=a[i]; ans+=v[sum][i&1]; v[sum][i&1]++; } printf("%I64d\n",ans); return 0;}
View Code

 

1109B. Sasha and One More Name

对于一个长度为 $n$ 的回文串,只有当相同字母数 $\le n-1$ 时,才一定存在答案。否则一定无解。

考虑什么时候会有答案为 $1$ :

切一刀变成回文串,相当于把这个串结成一个环,如果从一个地方切下一刀形成的链得到与原串不相同的回文串,那么切一刀合法。

剩余的所有情况,因为我们保证回文串一定在对称的部分存在不同字母,那么一定存在一种情况在两边对称的地方切一刀,左右交换,得到新的回文串。

以下代码:

#include
#define il inline#define _(d) while(d(isdigit(ch=getchar())))using namespace std;const int N=5005;char s[N<<1];int n;il int read(){ int x,f=1;char ch; _(!)ch=='-'?f=-1:f;x=ch^48; _()x=(x<<1)+(x<<3)+(ch^48); return f*x;}il bool pd0(){ int mid=n>>1; for(int i=1;i
>1; for(int i=1;i<=mid;i++){ int j=l+n-i; if(s[l+i-1]!=s[j])return 0; } for(int i=1;i<=n;i++)if(s[i]!=s[i+l-1])return 1; return 0;}il bool pd1(){ for(int i=2;i<=n;i++){ if(pd(i))return 1; } return 0;}int main(){ scanf(" %s",s+1);n=strlen(s+1); for(int i=1;i<=n;i++)s[i+n]=s[i]; if(n<=3||!pd0())return puts("Impossible"),0; if(pd1())return puts("1"),0; puts("2"); return 0;}
View Code

 

1109D. Sasha and Interesting Fact from Graph Theory

测试的时候看错题目了气哭!

考虑枚举在 $a,b$ 之间点的个数。

$$
ans=\sum_{i=0}^{min(m-1,n-2)}C_{n-2}^{i}i!C_{m-1}^{i}(i+2)n^{n-i-3}m^{n-i-2}
$$
$C_{n-2}^{i}$ 表示在除 $a,b$ 外的点中选出 $i$ 个点作为 $a,b$ 链上的点

$i!$ 表示 $a,b$ 之间的点的排列顺序

$C_{m-1}^{i}$ 表示 $a,b$ 链之间的点的长度分布(插板法)

$(i+2)n^{n-i-3}$ 表示不在链上的点的分布的方案数()

$m^{n-i-2}$ 表示不在链上每个点连接的边不同长度的方案数

以下代码:

#include
#define il inline#define LL long long#define _(d) while(d(isdigit(ch=getchar())))using namespace std;const int N=1e6+5,p=1e9+7;int n,m,jc[N],ny[N],ans,po[N],M[N],mx;il int read(){ int x,f=1;char ch; _(!)ch=='-'?f=-1:f;x=ch^48; _()x=(x<<1)+(x<<3)+(ch^48); return f*x;}il int ksm(LL a,int y){ LL b=1; while(y){ if(y&1)b=b*a%p; a=a*a%p;y>>=1; } return b;}il int mu(int x,int y){ return (x+y>=p)?x+y-p:x+y;}il int C(int n,int m){ return 1ll*jc[n]*ny[m]%p*ny[n-m]%p;}int main(){ n=read();m=read();read();read();mx=max(n,m); jc[0]=1;for(int i=1;i<=mx;i++)jc[i]=1ll*i*jc[i-1]%p; ny[mx]=ksm(jc[mx],p-2);for(int i=mx;i;i--)ny[i-1]=1ll*i*ny[i]%p; po[0]=1;for(int i=1;i<=mx;i++)po[i]=1ll*n*po[i-1]%p; M[0]=1;for(int i=1;i<=mx;i++)M[i]=1ll*m*M[i-1]%p; for(int i=0;i<=min(m-1,n-2);i++){ if(i==n-2)ans=mu(ans,1ll*C(m-1,i)*jc[i]%p); else ans=mu(ans,1ll*C(n-2,i)*jc[i]%p*C(m-1,i)%p*(i+2)%p*po[n-i-3]%p*M[n-i-2]%p); } printf("%d\n",ans); return 0;}
View Code

1109E. Sasha and a Very Easy Test

因为模数非质数,考虑对模数质因数分解,不同质因数的个数最多只有 $10$ 个,于是我们用线段树维护区间的和,和乘法操作举荐的标记,以及每个位置每个数的权值以及对于以模数的每个质因数作为底数的指数是多少。对于除法操作可以减去除数对应质因数指数,同时对于不包含在质因数的部分与模数互质,可以用欧拉定理求逆元计算得。

以下代码:

#include
#define il inline#define LL long long#define _(d) while(d(isdigit(ch=getchar())))using namespace std;const int N=1e5+5;int n,p,b[12],t,f,c[N];il int ksm(LL a,int y){ LL b=1; while(y){ if(y&1)b=b*a%p; a=a*a%p;y>>=1; } return b;}struct node{ int s,r,a[12],d; void clear(){ for(int i=1;i<=t;i++)a[i]=0; r=d=1; } void operator+=(node x){ for(int i=1;i<=t;i++)a[i]+=x.a[i]; r=1ll*r*x.r%p;s=1ll*s*x.d%p;d=1ll*d*x.d%p; } void operator-=(node x){ r=1ll*r*ksm(x.r,f-1)%p;s=r; for(int i=1;i<=t;i++)a[i]-=x.a[i],s=1ll*s*ksm(b[i],a[i])%p; d=s; } void operator^=(int x){ clear();s=d=x%p; for(int i=1;i<=t;i++){ while(!(x%b[i]))a[i]++,x/=b[i]; } r=x%p; }}val[N<<2],d;il int read(){ int x,f=1;char ch; _(!)ch=='-'?f=-1:f;x=ch^48; _()x=(x<<1)+(x<<3)+(ch^48); return f*x;}il int mu(int x,int y){ return (x+y>=p)?x+y-p:x+y;}il void update(int x){ val[x].s=mu(val[x<<1].s,val[x<<1|1].s);}il void pushdown(int x){ if(val[x].d==1)return; val[x<<1]+=val[x]; val[x<<1|1]+=val[x]; val[x].clear();}il void build(int x,int l,int r){ if(l==r){val[x]^=c[l];return;} int mid=(l+r)>>1;val[x].clear(); build(x<<1,l,mid);build(x<<1|1,mid+1,r); update(x);}il void mul(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){val[x]+=d;return;} int mid=(l+r)>>1;pushdown(x); if(ql<=mid)mul(x<<1,l,mid,ql,qr); if(mid
<<1|1,mid+1,r,ql,qr); update(x);}il void div(int x,int l,int r,int pos){ if(l==r){val[x]-=d;return;} int mid=(l+r)>>1;pushdown(x); if(pos<=mid)div(x<<1,l,mid,pos); else div(x<<1|1,mid+1,r,pos); update(x);}il int query(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr)return val[x].s; int mid=(l+r)>>1;pushdown(x); int res=0; if(ql<=mid)res=query(x<<1,l,mid,ql,qr); if(mid
<<1|1,mid+1,r,ql,qr)); return res;}int main(){ n=read();p=read();int tmp=p; for(int i=2;i*i<=tmp;i++){ if(!(tmp%i)){ b[++t]=i; while(!(tmp%i))tmp/=i; } } if(tmp>1)b[++t]=tmp;f=p; for(int i=1;i<=t;i++)f-=f/b[i]; for(int i=1;i<=n;i++)c[i]=read(); build(1,1,n);int Q=read(); while(Q--){ int op=read(); if(op==1){ int x=read(),y=read(),z=read(); d^=z;mul(1,1,n,x,y); } else if(op==2){ int x=read(),z=read(); d^=z;div(1,1,n,x); } else{ int x=read(),y=read(); printf("%d\n",query(1,1,n,x,y)); } } return 0;}
View Code

 

转载于:https://www.cnblogs.com/Jessie-/p/10504903.html

你可能感兴趣的文章
Codekit - 为Web前端打造的全能型神器(附推荐各种工具)
查看>>
java 截取字符串 拆分字符串
查看>>
从零开始学C++之数据封装与抽象:分别用C和C++来实现一个链栈
查看>>
[置顶] IT老男人读《因为痛,所以叫青春》
查看>>
Android NDK学习(3)使用Javah命令生成JNI头文件 .
查看>>
poj2186Popular Cows(Kosaraju算法--有向图的强连通分量的分解)
查看>>
LR基础学习_脚本信息函数
查看>>
基于html5 canvas和js实现的水果忍者网页版
查看>>
2、传统的线程互斥synchronized
查看>>
IT忍者神龟之使用 PowerDesigner
查看>>
JSP导出Excel文件
查看>>
谷歌大神Jeff Dean:大规模深度学习最新进展 zz
查看>>
javaweb学习总结(八)——HttpServletResponse对象(二)
查看>>
CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能
查看>>
jquery------提供灵活的方法参数
查看>>
Android ContentProvider和getContentResolver
查看>>
深入理解javascript描述元素内容的5个属性
查看>>
Android 知识梳理
查看>>
poj 1331 Multiply
查看>>
解决java.lang.OutOfMemoryError: unable to create new native thread问题
查看>>