# Codeforces Global Round 10

## F Omkar and Landslide

### $Code$

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e6+10;
const int inf=1e9+10;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
int n,d,mx;
LL h[N];
int q[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%I64d",&h[i]);
int tp=1;q[1]=1;
LL nd,ud;
int x;
for(int i=2;i<=n;++i){
while(1){
if(h[i]==h[q[tp]]){
q[++tp]=i;
break;
}
if(h[i]==h[q[tp]]+1){
q[tp]=i;
break;
}
if(tp>=2){
nd=q[tp]-q[tp-1];
if(h[q[tp]]+1<=h[i]-nd){
h[i]-=nd;
h[q[tp]]++;
q[tp-1]=q[tp];
--tp;
}
else{
ud=h[i]-(h[q[tp]]+1);
q[tp-1]+=ud;
q[tp]=i;
h[i]=h[i]-ud;
break;
}
}
else {
nd=q[tp];
if(h[q[tp]]+1<=h[i]-nd){
ud=(h[i]-h[q[tp]])/(LL)(nd+1);
h[q[tp]]+=ud;
h[i]-=ud*nd;
}
else{
ud=h[i]-(h[q[tp]]+1);
q[tp]=ud;
q[tp+1]=i;
++tp;
h[i]=h[i]-ud;
break;
}
}
}
}
--tp;
for(int i=n-1;i>=1;--i){
h[i]=h[i+1]-1;
if(tp>0&&q[tp]==i){
++h[i];
--tp;
}
}
for(int i=1;i<=n;++i){
print(h[i]);putchar(' ');
}
puts("");
return 0;
}


## G Omkar and Pies

### $Code$

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=3e5+10;
const int inf=1e8;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
int n,m,K;
char s[30];
int a[30],b[30],p[30],bin[30];
int aa[30],bb[30];
int cnt[(1<<20)+10];
int dp[2][(1<<20)+10];
int getnum(int *c){
int re=0;
for(int i=K;i>=1;--i) re=re<<1|c[i];
return re;
}
void umin(int &x,int y){if(x>y)x=y;}
void umax(int &x,int y){if(x<y)x=y;}
int main(){
for(int i=0;i<=(1<<19);++i){
cnt[i<<1]=cnt[i];
cnt[i<<1|1]=cnt[i]+1;
}
scanf("%d%d%d",&n,&m,&K);
scanf("%s",s+1);
for(int i=1;i<=K;++i) a[i]=s[i]-'0';
scanf("%s",s+1);
for(int i=1;i<=K;++i) b[i]=s[i]-'0';
for(int i=0;i<=(1<<20);++i) dp[0][i]=inf;
for(int i=0;i<=(1<<20);++i) dp[1][i]=-inf;
umin(dp[0][getnum(a)],0);
umax(dp[1][getnum(b)],0);
for(int i=1;i<=K;++i) p[i]=i;
int l,r;
for(int i=1;i<=n;++i){
scanf("%d%d",&l,&r);
swap(p[l],p[r]);
for(int j=1;j<=K;++j){
aa[p[j]]=a[j];
bb[p[j]]=b[j];
}
//for(int j=1;j<=K;++j) cout<<aa[j]<<" ";puts("");
//for(int j=1;j<=K;++j) cout<<bb[j]<<" ";puts("");
umin(dp[0][getnum(aa)],i);
umax(dp[1][getnum(bb)],i);
}
for(int i=(1<<K)-1;i>0;--i){
for(int j=0;j<K;++j){
if(i&(1<<j)){
umin(dp[0][i-(1<<j)],dp[0][i]);
umax(dp[1][i-(1<<j)],dp[1][i]);
}
}
}
int ans=-1;
for(int i=0;i<(1<<K);++i){
if(cnt[i]>ans&&dp[1][i]-dp[0][i]>=m){
ans=cnt[i];
l=dp[0][i]+1;
r=dp[1][i];
}
}
ans=K+ans+ans;
for(int i=1;i<=K;++i) ans=ans-a[i]-b[i];
cout<<ans<<endl<<l<<" "<<r<<endl;
return 0;
}


## H ZS Shuffles Cards

### 题意

$n+m$ 张牌，其中有 $m$ 张鬼牌，剩余 $n$ 张牌有编号 $1$$n$

### 题解

$f(x)$ $=$ $\sum_{l=0}^{x}{\sum_{i=0}^{n}{ {x \choose l} {n-x \choose i-l} \cdot i! \cdot m \cdot \frac{(n+m-i-1)!}{(n+m)!} \cdot (f(x-l)+i+1)}}$

$A(x)$ $=$ $\sum_{l=0}^{x}{\sum_{i=0}^{n}{ {x \choose l} {n-x \choose i-l} \cdot i! \cdot m \cdot \frac{(n+m-i-1)!}{(n+m)!} \cdot (i+1)}}$
$B(x)$ $=$ $\sum_{l=0}^{x}{\sum_{i=0}^{n}{ {x \choose l} {n-x \choose i-l} \cdot i! \cdot m \cdot \frac{(n+m-i-1)!}{(n+m)!} \cdot f(x-l)}}$
$f(x)$ $=$ $A(x)+B(x)$

$A(x)$ $=$ $\frac{m \cdot x! \cdot (n-x)!}{(n+m)!} \cdot \sum_{l=0}^{x}{ \frac{(m-1+x-l)! \cdot (l+1)}{(x-l)!} \cdot \sum_{i=0}^{n}{\frac{(i+1)!}{(l+1)! \cdot (i-l)!} \cdot \frac{(n+m-i-1)!}{(n-x-i+l)! \cdot (m-1+x-l)!} }}$
$A(x)$ $=$ $\frac{m \cdot x! \cdot (n-x)!}{(n+m)!} \cdot \sum_{l=0}^{x}{ \frac{(m-1+x-l)! \cdot (l+1)}{(x-l)!} \cdot \sum_{i=0}^{n}{ {i+1 \choose l+1} \cdot {n+m-i-1 \choose m-1+x-l} }}$
$A(x)$ $=$ $\frac{m \cdot x! \cdot (n-x)!}{(n+m)!} \cdot \sum_{l=0}^{x}{ \frac{(m-1+x-l)! \cdot (l+1)}{(x-l)!} \cdot {n+m+1 \choose m+x+1} }$ 这里用到了 $\sum_{i}{i \choose k}{n-i \choose m-k}$ $=$ ${n+1 \choose m+1}$ 这条公式，详见本博客的数学的专题总结。。
$A(x)$ $=$ $\frac{m \cdot x! \cdot (n-x)!}{(n+m)!} \cdot {n+m+1 \choose m+x+1} \cdot \sum_{l=0}^{x}{ \frac{(m+l-1)! \cdot (x-l+1)}{l!} }$

$B(x)$ $=$ $=$ $\frac{m \cdot x! \cdot (n-x)!}{(n+m)!} \cdot \sum_{l=0}^{x}{ \frac{(m-1+x-l)! \cdot f(x-l)}{(x-l)!} \cdot \sum_{i=0}^{n}{\frac{i!}{l! \cdot (i-l)!} \cdot \frac{(n+m-i-1)!}{(n-x-i+l)! \cdot (m-1+x-l)!} }}$
$B(x)$ $=$ $\frac{m \cdot x! \cdot (n-x)!}{(n+m)!} \cdot {n+m \choose m+x} \cdot \sum_{l=0}^{x}{ \frac{(m+l-1)! \cdot f(l)}{l!} }$
$B(x)$ $=$ $\frac{m \cdot x!}{(m+x)!} \cdot \sum_{l=0}^{x}{ \frac{(m+l-1)! \cdot f(l)}{l!} }$

### $Code$

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2e6+10;
const int inf=1e8;
const LL P=998244353;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
LL n,m;
LL jc[N*3],inv[N*3];
LL f[N],A[N],B[N];
LL T[N],G[N],H[N];
x+=y;if(x>=P)x-=P;
}
LL qpow(LL x,LL y){
LL re=1;
while(y){
if(y&1) re=re*x%P;
x=x*x%P;y>>=1;
}
return re;
}
int main(){
jc[0]=jc[1]=inv[0]=inv[1]=1;
for(LL i=2;i<=N*2;++i){
jc[i]=jc[i-1]*i%P;
inv[i]=(P-P/i)*inv[P%i]%P;
}
for(LL i=2;i<=N*2;++i){
inv[i]=inv[i-1]*inv[i]%P;
}
cin>>n>>m;
T[0]=jc[m-1];G[0]=jc[m-1];
for(LL i=0;i<n;++i){
}
for(LL i=1;i<=n;++i){
A[i]=m*jc[i]%P*(n+m+1)%P*inv[m+i+1]%P*T[i]%P;
B[i]=m*jc[i]%P*inv[m+i]%P*H[i-1]%P;
f[i]=(A[i]+B[i])%P*qpow((P+1-m*inv[m+i]%P*jc[m-1+i]%P)%P,P-2)%P;
}
cout<<f[n]<<endl;
return 0;
}


## I Kevin and Grid

### 题解

（出题人原话“However, some faces are not interesting, namely the 2×2 square of adjacent cells.”）这句话我当时懵逼了一天。。

$ans(x)$ $=$ $(C_1-1)+(F_2-1-Q_2)-(C_2-1)-(F_1-1-Q_1)$
$ans(x)$ $=$ $C_1+F_2-C_2-F_1+Q_1-Q_2$

$ans(x)$ $=$ $V_1-E_1-V_2+E_2+Q_1-Q_2$

### $Code$

#include <bits/stdc++.h>
#define DB long double
#define LL long long
using namespace std;
const int N=4e5+10;
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
const DB PI=acos(-1);
struct V{
DB x,y;
V(DB _x=0,DB _y=0){x=_x;y=_y;}
};
V operator + (V a,V b){return V(a.x+b.x,a.y+b.y);}
V operator - (V a,V b){return V(a.x-b.x,a.y-b.y);}
V operator * (V a,V b){return V(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
struct FastFourierTransform{
int n,rev[N];
void init(int m){
n=1;
while(n<m) n<<=1;
int k=0;
while((1<<k)<n) ++k;
for(int i=0;i<n;++i){
int t=0;
for(int j=0;j<k;++j) if(i&(1<<j)) t|=(1<<(k-j-1));
rev[i]=t;
}
}
void DFT(V *a,int flag){
for(int i=0;i<n;++i) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int l=2;l<=n;l<<=1){
int m=l>>1;
V wn(cos(2*PI/l),flag*sin(2*PI/l));
for(V *p=a;p!=a+n;p+=l){
V w(1,0);
for(int k=0;k<m;++k){
V t=w*p[k+m];
p[k+m]=p[k]-t;
p[k]=p[k]+t;
w=w*wn;
}
}
}
if(flag==-1) for(int i=0;i<n;++i) a[i].x/=n;
}
void Cheng(V *a,V *b,int m){
init(m);
DFT(a,1);DFT(b,1);
for(int i=0;i<n;++i) a[i]=a[i]*b[i];
DFT(a,-1);
}
}fft;
V A[N],B[N];
V Amx[N],Bmx[N];
V Amn[N],Bmn[N],C[N],D[N];

int n,m,Q;
int a[N],b[N];
LL ans[N];
int main(){
scanf("%d%d%d",&n,&m,&Q);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i) {
A[a[i]].x+=1;
if(i<n){
Amx[max(a[i],a[i+1])].x+=1;
Amn[min(a[i],a[i+1])].x+=1;
}
}
for(int i=1;i<=m;++i) scanf("%d",&b[i]);
for(int i=1;i<=m;++i) {
B[b[i]].x+=1;
if(i<m){
Bmx[max(b[i],b[i+1])].x+=1;
Bmn[min(b[i],b[i+1])].x+=1;
}
}
int L=200000+3;fft.init(L);
fft.DFT(A,1);fft.DFT(B,1);
fft.DFT(Amx,1);fft.DFT(Amn,1);
fft.DFT(Bmx,1);fft.DFT(Bmn,1);
for(int i=0;i<fft.n;++i){
C[i]=Amn[i]*Bmn[i];
D[i]=Amx[i]*Bmx[i];
Amn[i]=Amn[i]*B[i];Amx[i]=Amx[i]*B[i];
Bmn[i]=Bmn[i]*A[i];Bmx[i]=Bmx[i]*A[i];
A[i]=A[i]*B[i];
}
fft.DFT(C,-1);fft.DFT(D,-1);
fft.DFT(Amn,-1);fft.DFT(Amx,-1);
fft.DFT(Bmn,-1);fft.DFT(Bmx,-1);
fft.DFT(A,-1);
LL now=0;
for(int i=fft.n-1;i>=0;--i){
now+=(long long)(A[i].x+0.5);
ans[i]+=now;
}
now=0;
for(int i=0;i<fft.n;++i){
now+=(long long)(A[i].x+0.5);
ans[i+1]-=now;
}
now=0;
for(int i=fft.n-1;i>=0;--i){
now+=(long long)(C[i].x+0.5);
ans[i]+=now;
}
now=0;
for(int i=0;i<fft.n;++i){
now+=(long long)(D[i].x+0.5);
ans[i+1]-=now;
}
now=0;
for(int i=0;i<fft.n;++i){
now+=(long long)(Amx[i].x+0.5);
now+=(long long)(Bmx[i].x+0.5);
ans[i+1]+=now;
}
now=0;
for(int i=fft.n-1;i>=0;--i){
now+=(long long)(Amn[i].x+0.5);
now+=(long long)(Bmn[i].x+0.5);
ans[i]-=now;
}
int x;
while(Q--){
scanf("%d",&x);
printf("%I64d\n",ans[x]);
}
return 0;
}


posted @ 2020-08-27 19:10  Iscream-2001  阅读(247)  评论(0编辑  收藏  举报
/* */