TLE35分求助
查看原帖
TLE35分求助
124218
SpadeA261楼主2021/7/11 11:14

本人翻了n年前就TLE的这道题卡常重构,但分数仍旧没变,怀疑不是卡常的问题。

提交记录

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=1<<21;
int m,mod=998244353,p=31596;
int inv2=(mod+1)/2;
long long len=1,L;
int rev[N];
int power(int b,int p)
{
    int ans=1;
	while(p)
	{
		if(p&1) ans=1ll*ans*b%mod;
		p>>=1;
		b=1ll*b*b%mod;
	}
    return ans;
}
void add(int &x,int y)
{
    x+=y;
    x-=x>=mod?mod:0;
}
void sub(int &x,int y)
{
    x-=y;
    x+=x<0?mod:0;
}
int add(int x)
{
    return x>=mod?x-mod:x;
}
int sub(int x)
{
    return x<0?x+mod:x;
}
void NTT(int *x,int len,int opt)
{
    for(int i=0;i<len;i++)
    {
        if(rev[i]>i) swap(x[i],x[rev[i]]);
    }
    for(int h=2;h<=len;h<<=1)
    {
        int gn=power(3,(mod-1)/h);
        for(int i=0;i<len;i+=h)
        {
            int g=1;
            for(int j=0;j<h/2;j++)
            {
                int k=i+j;
                int tmp=1ll*g*x[k+h/2]%mod;
                x[k+h/2]=sub(x[k]-tmp);
                x[k]=add(x[k]+tmp);
                g=1ll*g*gn%mod;
            }
        }
    }
    if(opt==-1)
    {
        reverse(x+1,x+len);
        int inv=power(len,mod-2);
        for(int i=0;i<len;i++) x[i]=1ll*x[i]*inv%mod;
    }
}
typedef vector<int> F;
F fix(F a,int len)
{
    // for(int i=0;i<a.size();i++) cout<<a[i]<<" ";
    // cout<<endl;
    a.resize(len);
    return a;
}
void print(F a)
{
    int len=a.size();
    for(int i=0;i<len;i++) printf("%d ",a[i]);
    printf("\n");
}
F operator+(F a,F b)
{
    int lena=a.size(),lenb=b.size();
    int len=max(lena,lenb);
    a.resize(len);
    for(int i=0;i<len;i++) add(a[i],b[i]);
    return a;
}
F operator-(F a,F b)
{
    int lena=a.size(),lenb=b.size();
    int len=max(lena,lenb);
    a.resize(len);
    for(int i=0;i<len;i++) sub(a[i],b[i]);
    return a;
}
F operator*(F a,int b)
{
    int lena=a.size();
    for(int i=0;i<lena;i++) a[i]=1ll*a[i]*b%mod;
    return a;
}
F operator*(F a,F b)
{
    if(a.empty()||b.empty()) return F();
    int lena=a.size(),lenb=b.size();
    int lenab=lena+lenb-1;
    for(len=1,L=0;len<=lena+lenb;len<<=1,L++);
    for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
    a.resize(len);
    b.resize(len);
    NTT(&a[0],len,1);
    NTT(&b[0],len,1);
    for(int i=0;i<len;i++) a[i]=1ll*a[i]*b[i]%mod;
    NTT(&a[0],len,-1);
    return fix(a,lenab);
}
F Inv(F a)
{
	int len=a.size();
	if(len==1)
    {
        F ans;
        ans.push_back(power(a[0],mod-2));
        return ans;
    }
	F b=Inv(fix(a,(len+1)/2));
	return fix(b*2-b*b*a,len);
}
F Sqrt(F a)
{
    int len=a.size();
    if(len==1) return F(1,sqrt(a[0]));
	F b=fix(Sqrt(fix(a,(len+1)/2)),len);
	return fix((b+a*Inv(b))*inv2,len);
}
inline int read()
{
    int x=0;
    char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch))
    {
        x=x*10+ch-48;
        ch=getchar();
    }
    return x;
}
signed main()
{
    freopen("P5395.in","r",stdin);
    int n=read();
    F a;
    for(int i=0;i<n;i++) a.push_back(read());
    print(Sqrt(a));
    return 0;
}
2021/7/11 11:14
加载中...