海亮Day2:

T1:小刚的传说

题目:
感谢YYC大佬洛谷造题:小刚的传说
题解:
就是个LCA倍增裸题,距离表示为 d e e p [ i ] + d e e p [ i + 1 ] − 2 ∗ l c a ( i , i + 1 ) deep[i]+deep[i+1]-2*lca(i,i+1) deep[i]+deep[i+1]2lca(i,i+1)
AC代码:

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int s=0,w=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1; ch=getchar();}
	while(ch<='9'&&ch>='0') s=s*10+ch-'0',ch=getchar();
	return s*w;
}
const int sea=200100;
struct see{int x,ver,next;}e[sea<<1];
int n,m,k,tot,kkk=21,last[sea<<1],fa[30][sea],deep[sea],a[sea];
void add(int x,int y){e[++tot].x=x,e[tot].ver=y;e[tot].next=last[x];last[x]=tot;}
void dfs(int x,int d)
{
	fa[0][x]=d; deep[x]=deep[d]+1;
	for(int i=last[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		if(y!=fa[0][x]) dfs(y,x);
	} 
}
void bz()
{
	dfs(1,0);
	for(int i=1;1<<i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		if(fa[i-1][j]<0) fa[i][j]=-1;
		else fa[i][j]=fa[i-1][fa[i-1][j]];
	}
	return;
}
int lca(int x,int y)
{
	if(deep[x]>deep[y]) swap(x,y);
	for(int d=deep[y]-deep[x],i=0;d;d>>=1,i++) if(d&1) y=fa[i][y];
	if(x==y) return x;
	for(int i=kkk;i>=0;--i) if(fa[i][x]!=fa[i][y]) x=fa[i][x],y=fa[i][y];
	return fa[0][x];
}
int main()
{
	n=read();
	for(int i=1;i<n;i++) 
	{
		a[i]=read();
		add(a[i],i+1);add(i+1,a[i]);
	}
	deep[0]=0;	bz(); int ans;
	for(int i=1;i<n;i++)
	{
		if((i+1)!=lca(i,i+1)) ans=abs(deep[i]-deep[lca(i,i+1)])+abs(deep[i+1]-deep[lca(i,i+1)]);
		else ans=abs(deep[i]-deep[i-1]);
		printf("%d\n",ans);
	}
	return 0;
}

T2:中珂院的难题

题目:中珂院的难题
题解:
(表示自己看的懂题解,但是写不出来代码,,)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(直接粘了chty大佬的题解)
代码:

#include<bits/stdc++.h>
#define MAXN 100010
#define cadd(a,b) a=add(a,b)
#define csub(a,b) a=sub(a,b)
using namespace std;
const int mod=1e9+7;
int n,m,a[MAXN],fac[MAXN<<1],inv[MAXN<<1],s[105][MAXN];
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
	return x*f;
}
inline int Pow(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=mul(ret,a);
		b>>=1; a=mul(a,a);
	}
	return ret;
}
inline int C(int a,int b){return mul(fac[a],mul(inv[b],inv[a-b]));}
inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
inline int sub(int a,int b){return (a-=b)<0?a+mod:a;}
inline int mul(int a,int b){return 1LL*a*b%mod;}
int main()
{
	n=read(); m=read(); int N=200000; fac[0]=1;
	for(int i=1;i<=n;++i) a[i]=read();
	for(int i=1;i<=N;++i) fac[i]=mul(fac[i-1],i); inv[N]=Pow(fac[N],mod-2);
	for(int i=N-1;i>=0;--i) inv[i]=mul(inv[i+1],i+1);
	for(int i=1;i<=m;++i)
	{
		int l=read(),r=read(),K=read();
		cadd(s[K+1][l],1);
		for(int k=1;k<=K+1;++k) csub(s[k][r+1],C(K+1-k+r-l,K+1-k));
	}
	for(int k=100;k>=0;--k)
	{
		int cnt=0;
		for(int i=1;i<=n;++i) cadd(cnt,s[k+1][i]),cadd(s[k][i],cnt);
	}
	for(int i=1;i<=n;++i)printf("%d ",add(a[i],s[0][i]));
	return 0;
}
//署名:chyt_syq

T3:欧拉图

题目链接:欧拉图
题解:还以为是结论题,就推了好长好长时间,但是正解是递推,懵,,,
在这里插入图片描述
这样的话进行就可以用生成函数(分治FFT)进行加速了。
在这里插入图片描述
(看完题解后,很显然,我是想不到正解的,再次很显然,没有好好学递推的我是想不到60分的做法的,再很显然以为是结论题的我这道题直接爆0了)

代码:

#include<bits/stdc++.h>
#define FILE "euler"
#define MAXN 600100
using namespace std;
const int mod(998244353),G(3);
int n,a[MAXN],b[MAXN],temp[MAXN],inva[MAXN],R[MAXN],da[MAXN],w[MAXN],inv[MAXN],fac[MAXN],wn[2][20];
inline int read(){
    int x=0,f=1;  char ch=getchar();
    while(ch>'9'||ch<'0')  {if(ch=='-')  f=-1;  ch=getchar();}
    while(ch>='0'&&ch<='9')  {x=x*10+ch-'0';  ch=getchar();}
    return x*f;
}
inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
inline int sub(int a,int b){return (a-=b)<0?a+mod:a;}
inline int mul(int a,int b){return 1LL*a*b%mod;}
inline int fast(int a,long long b){int ret(1);for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
void pre(){
    w[0]=1;
    wn[0][18]=fast(G,(mod-1)/(1<<18));
    wn[1][18]=fast(wn[0][18],mod-2);
    for(int i=17;i>=0;--i)for(int k=0;k<=1;++k)wn[k][i]=mul(wn[k][i+1],wn[k][i+1]);
}
void NTT(int *a,int H,int f=0){
    int L=(1<<H);
    for(int i=0;i<L;++i) if(i<(R[i]=(R[i>>1]>>1)|((i&1)<<(H-1)))) swap(a[i],a[R[i]]);
    for(int e=1;e<=H;++e){
        int len=(1<<e),l=(len>>1);
        for(int i=1;i<l;++i) w[i]=mul(w[i-1],wn[f][e]);
        for(int st=0;st<L;st+=len)for(int k=0;k<l;++k){
            int x=a[st+k],y=mul(w[k],a[st+k+l]);
            a[st+k]=add(x,y); a[st+k+l]=sub(x,y);
        }
    }
    if(f) for(int i=0,temp=fast(L,mod-2);i<L;++i) a[i]=mul(a[i],temp);
}
void getinv(int *a,int L,int *b){
    b[0]=fast(a[0],mod-2);
    for(int now=0;(1<<now)<L;++now){
        int l=(1<<(now+1));
        for(int i=0;i<l;++i) temp[i]=a[i];
        for(int i=l;i<(l<<1);++i) temp[i]=0;
        NTT(temp,now+2); NTT(b,now+2);
        for(int i=0;i<(l<<1);++i) b[i]=mul(b[i],sub(2,mul(temp[i],b[i])));
        NTT(b,now+2,1);
        for(int i=l;i<(l<<1);++i) b[i]=0;
    }
    for(int i=L;i<(L<<1);++i) b[i]=0;
}
void getIn(int *a,int H,int *b){
    int L=(1<<H);  getinv(a,L,inva);
    for(int i=0;i<L;++i) da[i]=mul(a[i+1],i+1);
    NTT(inva,H);  NTT(da,H);
    for(int i=0;i<L;++i) temp[i]=mul(inva[i],da[i]);
    NTT(temp,H,1);
    for(int i=1;i<L;++i) b[i]=mul(temp[i-1],fast(i,mod-2));
}
int main(){
    freopen(FILE".in","r",stdin);
    freopen(FILE".out","w",stdout);
    n=read();  pre();
    int L=1,H=0; while(L<=n) L<<=1,++H;
    fac[0]=1; for(int i=1;i<=L;++i) fac[i]=mul(fac[i-1],i);
    inv[L]=fast(fac[L],mod-2);
    for(int i=L-1;i>=0;--i) inv[i]=mul(inv[i+1],i+1);
    for(int i=1;i<=n;++i) a[i]=mul(fast(2,(long long)(i-2)*(i-1)/2),inv[i]);
    a[0]=1;  getIn(a,H,b);
	int ans=mul(b[n],fac[n]);
    printf("%d\n",ans);
    return 0;
}

(根据往常的习惯,肯定还会有我自己的代码,等我回去了就好好搞一下,一定补,一定补,,)

Day2,就这样子结束了,,,

Tomorrow continue……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值