21杭电多校第七场

A

很猛的题 咕了

B

线段树计数 咕了

C

签到题,推个式子,大概是拆成了一些等比的三角形以及面积为等差乘等比的矩形面积和

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-b+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
db n,x,y,x1,y1,x2,y2,ans,res;
db qp(db x,int t,db res=1)
{
	for(;t;t>>=1,x=x*x) if(t&1) res=res*x;return res;
}
int main()
{
	rep(T,1,read())
	{
		n=read()-2;x=read(),y=read(),x1=read(),y1=read(),x2=read(),y2=read();
		int tx=x2-x,ty=abs(y1-y);
		res=ans=(2-qp(0.5,n))*tx*ty;//cout<<ans<<endl;
		ans-=tx*ty;
		ans=tx*ty*n-ans;ans*=2;
		printf("%.3lf
",ans*2+res);
	}
}

D

本来是用生成函数做的,最后推出来答案是(frac{1-x^{n+1}}{(1-x)^{n+1}})幂级数展开后(x^m)的系数,但好像没有这个必要

将可以取([0,k-1])个球的框与只能取(k)的倍数个球的框合并为一个可以取任意个球的框

就得到了(n)个可以取任意个球的框和一个可以取([0,n])个球的框

枚举取([0,n])个球的框中取出了多少个球,剩下的球的选取方案可以由插板法得到

答案为(sumlimits_{i=0}^ninom{m-i+n-1}{n-1}),即(inom{n+m}{n}-inom{m-1}{n})

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 3001001
#define MOD 1000000007
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-b+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int fac[MAXN],ifac[MAXN],n,m;
int qp(int x,int t,int res=1)
{
	for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;
}
#define inv(x) qp(x,MOD-2)
int mem(int n=3e6)
{
	fac[0]=ifac[0]=1;rep(i,1,n) fac[i]=mul(fac[i-1],i);
	ifac[n]=inv(fac[n]);dwn(i,n-1,1) ifac[i]=mul(ifac[i+1],i+1);
}
int C(int n,int m)
{
	if(n<0||m<0||n<m) return 0;
	return mul(fac[n],mul(ifac[n-m],ifac[m]));
}
int main()
{
	mem();rep(T,1,read())
	{
		n=read(),m=read();
		printf("%d
",mns(C(n+m,m),C(m-1,m-n-1)));
	}
}

E

可以发现在第一个人的位置确定之后,之后的人数总数是确定的

可以预处理(f_i)表示长度为(i)的空位两边坐了人后的人数,(g_i)表示一边坐了人,另一边为桌子的人数

则可以得到答案为(ans_n=1+frac{1}{n}sumlimits_{i=1}^ng_{i-1}+g_{n-i}=1+frac{2}{n}sumlimits_{i=0}^{n-1}g_i)

预处理(g)的前缀和即可解决

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 1001001
#define MOD 1000000007
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,f[MAXN],g[MAXN],sum[MAXN],ans;
void mem(int n=1e6)
{
	rep(i,3,n) f[i]=1+f[(i-1)/2]+f[i/2];
	rep(i,2,n) g[i]=1+f[i-1];
	rep(i,1,n) sum[i]=pls(g[i],sum[i-1]);
}
int qp(int x,int t,int res=1)
{
	for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);
	return res;
}
int main()
{
	mem();rep(T,1,read())
	{
		n=read();if(n<=2) {puts("1");continue;}
		printf("%d
",pls(1,qp(n,MOD-2,mul(2,sum[n-1]))));
	}
}

F

将手雷的运动分解为竖直向下的匀加速直线运动和(vt)的匀速直线运动,固定人的位置不动后,手雷可能出现的位置在一个球上,所求即为手雷的球被人周围半径为(r)的圆包含部分的面积

特判一定爆炸和不会炸到的情况后,一般情况下(t)秒后二者位置如图

image

对右图( heta)列余弦定理有:(v_0gt^3cos heta=(frac{1}{2}gt^2)^2+(v_0t)^2-r^2)

由球冠面积公式得:(S=2pi(v_0t)^2(1-cos heta)),因此答案为(1-frac{S}{S_0}=frac{1+cos heta}{2})

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 1000000007
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline int sqr(int x) {return x*x;}
int qp(int x,int t,int res=1)
{
	for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);
	return res;
}
int v,r,t,ans;
int main()
{
	rep(T,1,read())
	{
		t=read(),v=read(),r=read();
		if(r>=5*t*t+v*t) {puts("0");continue;}
		if(r+v*t<=5*t*t||r+5*t*t<=v*t) {puts("1");continue;}
		ans=sqr(5*t*t)+sqr(v*t)-sqr(r);
		ans=qp(mul(v*10,t*sqr(t)),MOD-2,ans);
		ans=qp(2,MOD-2,pls(1,ans));
		printf("%d
",(ans+MOD)%MOD);
	}
}

G

每个点的答案显然为这个点最终走到环的平均权值

搜出所有环之后判一下所有环的平均权值是否相等

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 300100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,to[MAXN],ans,vis[MAXN],tot;ll sum,cnt;
ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
void dfs(int x)
{
	if(vis[x]&&vis[x]!=tot) return ;
	else if(vis[x]==tot)
	{
		int tmp=to[x];ll s=x,c=1,g;
		while(tmp!=x) s+=tmp,c++,tmp=to[tmp];
		g=gcd(s,c),s/=g,c/=g;
		if(!sum) sum=s,cnt=c;
		else if(sum!=s||cnt!=c) ans=0;
		return ;
	}
	vis[x]=tot;dfs(to[x]);
}
int main()
{
	rep(T,1,read())
	{
		n=read();tot=0,ans=1,sum=0;rep(i,1,n) to[i]=read(),vis[i]=0;
		rep(i,1,n) if(!vis[i]) {++tot;dfs(i);}
		puts(ans?"YES":"NO");
	}
}

H

签到题,按照题意模拟蛇怎么走即可

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-b+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,x,y,d,a,b,g1,g2;
int main()
{
	rep(T,1,read())
	{
		x=read(),y=read(),d=read(),n=read();
		rep(i,1,n)
		{
			a=read(),b=read();
			if(a>x) g1=1;else g1=3;
			if(b>y) g2=0;else g2=2;
			if(d!=g1&&d!=g2)
			{
				if((d+1)%4==g1||(d+1)%4==g2) putchar('c'),d=(d+1)%4;
				else putchar('u'),d=(d+3)%4;
			}
			if(d==g1)
			{
				rep(j,1,abs(a-x)) putchar('f');
				if(g2==(g1+1)%4) putchar('c');
				else putchar('u');
				rep(j,1,abs(b-y)) putchar('f');
				d=g2;
			}
			else if(d==g2)
			{
				rep(j,1,abs(b-y)) putchar('f');
				if(g1==(g2+1)%4) putchar('c');
				else putchar('u');
				rep(j,1,abs(a-x)) putchar('f');
				d=g1;
			}
			x=a,y=b;
		}
		puts("");
	}
}

I

计算几何 咕了

J

池中冰红茶的体积满足微分方程:

[egin{cases} V'(t)=(q-p)V(t)\V(0)=1 end{cases} ]

解得:(V(t)=e^{(q − p)t}),事实上需要判别反常积分(int_0^{+infty}V(t)dt)是否收敛,对其求不定积分得:

[int{V(t)dt=}egin{cases} V'(t)=(q-p)e^{(q-p)t}&q eq p\t&q=p end{cases} ]

可得只有当(q<p)时收敛

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-b+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int main()
{
	db a,b;
	rep(T,1,read())
	{
		cin>>a>>b;
		puts(a<=b?"N0 M0R3 BL4CK 1CE TEA!":"ENJ0Y YOURS3LF!");
	}
}

K

考虑构成数(x)的集合有(cnt_x)种方案,则(ans=sumlimits_{i=0}^wi^{cnt_i}),特判掉存在(0)的情况

(cnt)可以将每个数(t)认为是一个(1+x^t)的多项式,最终(cnt)即为所有多项式的卷积

使用堆优化卷积,注意(cnt)在指数上,需要(MTT)

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define Clear(x) {x.clear();vector<int> (x).swap(x);}
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const ld pi=acosl(-1);
namespace Poly
{
	struct Cd{ld x,y;Cd(ld X=0,ld Y=0){x=X,y=Y;};};
	Cd operator + (Cd a,Cd b) {return (Cd){a.x+b.x,a.y+b.y};}
	Cd operator - (Cd a,Cd b) {return (Cd){a.x-b.x,a.y-b.y};}
	Cd operator * (Cd a,Cd b) {return (Cd){a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y};}
	Cd operator / (Cd a,ld b) {return (Cd){a.x/b,a.y/b};}
	int rev[MAXN<<2];
	int mem(int n)
	{
		int lg=0,lim=1;for(;lim<n;lim<<=1,lg++);
		rep(i,0,lim-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
		return lim;
	}
	void fft(Cd *a,int n,int f)
	{
	    rep(i,0,n-1) if(i<rev[i]) swap(a[i],a[rev[i]]);
	    for(int i=1;i<n;i<<=1)
	    {
	        Cd wn(cosl(pi/i),f*sinl(pi/i));
	        for(int j=0;j<n;j+=i<<1)
	        {
	            Cd w(1,0),x,y;
	            for(int k=0;k<i;k++,w=w*wn)
	                x=a[k+j],y=a[k+j+i]*w,a[j+k]=x+y,a[j+k+i]=x-y;
	        }
	    }
	    if(f==1) return ;rep(i,0,n-1) a[i]=a[i]/n;
	}
	int Mul(int *res,int *a,int n,int *b,int m,int mod)
	{
		static Cd A[MAXN<<2],B[MAXN<<2],R[MAXN<<2];int s=mem(n+m-1);
		rep(i,0,n-1) A[i]=Cd(a[i]>>15,a[i]&0x7fff);
		rep(i,0,m-1) B[i]=Cd(b[i]>>15,b[i]&0x7fff);
		fill(A+n,A+s,Cd());fill(B+m,B+s,Cd());
		fft(A,s,1);fft(B,s,1);
		int j;rep(i,0,s-1)
		{
			j=(s-i)&(s-1);
            R[i]=B[i]*Cd(0.5*(A[i].x+A[j].x),0.5*(A[i].y-A[j].y));
            B[i]=B[i]*Cd(0.5*(A[i].y+A[j].y),0.5*(A[j].x-A[i].x));
		}
		fft(R,s,-1);fft(B,s,-1);
		ll x,y,z,w;rep(i,0,n+m-2)
			x=roundl(R[i].x),y=roundl(R[i].y),z=roundl(B[i].x),w=roundl(B[i].y),
            res[i]=(((x%mod<<30)%mod+((y+z)%mod<<15)%mod+w%mod)%mod+mod)%mod;
        return n+m-1;
	}
}
int n,a[MAXN<<2],b[MAXN<<2],c[MAXN<<2],ans;
vector<int> p[MAXN];
struct cmp
{
	bool operator ()(int &x,int &y)
		{return p[x].size()>p[y].size();}
};
priority_queue<int,vector<int>,cmp> q;
int qp(int x,int t,int res=1)
{
	for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);
	return res;
}
int main()
{
	int x,y,la,lb;rep(T,1,read())
	{
		n=read(),ans=1;rep(i,1,n)
		{
			x=read();if(!x) ans=0;Clear(p[i]);
			p[i].pb(1);rep(j,1,x-1) p[i].pb(0);
			p[i].pb(1);q.push(i);
		}
		if(!ans) {puts("0");while(!q.empty()) q.pop();continue;}
		rep(ii,2,n)
		{
			x=q.top();q.pop();y=q.top();q.pop();la=0,lb=0;
			for(auto t:p[x]) a[la++]=t;
			//cout<<x<<": ";for(auto t:p[x]) cout<<t<<" ";puts("");
			for(auto t:p[y]) b[lb++]=t;
			//cout<<y<<": ";for(auto t:p[y]) cout<<t<<" ";puts("");
			la=Poly::Mul(c,a,la,b,lb,MOD-1);Clear(p[x]);
			rep(i,0,la-1) p[x].pb(c[i]);q.push(x);
			//for(auto t:p[x]) cout<<t<<" ";puts("
");
		}
		x=q.top();q.pop();
		rep(i,1,p[x].size()-1) ans=mul(ans,qp(i,p[x][i]));
		printf("%d
",ans);
	}
}

L

每个字符的贡献是独立的,令这个字符的出现位置为(pos)数组,(g_i=pos_i-pos_{i-1})(ans_i)表示(g_i)这一段的答案

可得(ans_i=g_isumlimits_{j=1}^{i-1}g_j(i-j)^2),令(f_{i}=frac{ans_{i+1}}{g_{i+1}}=sumlimits_{j=1}^{i}g_j(i-j+1)^2)

(f)差分得:(d_i=sumlimits_{j=1}^i(2i-2j+1)g_j),对(d)再差分得(d'_i=g_i+2sumlimits_{j=1}^{i-1}g_j)可以直接统计

反推回去即可得到所有(ans_i)

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
char ch[MAXN];
vector<int> v[26];
int n,ans,g[MAXN],m,sum,s[MAXN];
void work(int t)
{
	v[t].pb(n+1);m=sum=0;
	for(auto x:v[t]) g[++m]=x,s[m]=g[m]-g[m-1];
	rep(i,1,m) g[i]=s[i],s[i]=pls(pls(s[i],s[i-1]),sum),sum=pls(sum,2*g[i]);
	rep(i,1,m) s[i]=pls(s[i],s[i-1]);
	rep(i,1,m) ans=pls(ans,mul(s[i-1],g[i]));
	v[t].clear();
}
int main()
{
	rep(T,1,read())
	{
		scanf("%s",ch+1);n=strlen(ch+1);rep(i,1,n) v[ch[i]-'a'].pb(i);
		rep(i,0,25) if(v[i].size()) work(i);printf("%d
",ans);ans=0;
	}
}
原文地址:https://www.cnblogs.com/yyc-jack-0920/p/15130003.html