QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#736056#9120. Huge Segment Treeucup-team134TL 1850ms249044kbC++174.5kb2024-11-11 23:58:222024-11-11 23:58:23

Judging History

你现在查看的是最新测评结果

  • [2024-11-11 23:58:23]
  • 评测
  • 测评结果:TL
  • 用时:1850ms
  • 内存:249044kb
  • [2024-11-11 23:58:22]
  • 提交

answer

#include <bits/stdc++.h>

#define ll long long
#define pb push_back
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define ios ios_base::sync_with_stdio(false);cin.tie(NULL)
#define ld long double
#define li __int128

using namespace std;

mt19937 rng(time(NULL));
const int mod=998244353;
inline int add(int x,int y){int ret=x+y;if(ret>=mod)ret-=mod;return ret;}
inline int sub(int x,int y){int ret=x-y;if(ret<0)ret+=mod;return ret;}
inline int mul(int x,int y){return ((ll)x*y)%mod;}
inline int step(int base,int pw){int ret=1;while(pw){if(pw&1)ret=mul(ret,base);base=mul(base,base);pw>>=1;}return ret;}
inline int invv(int x){return step(x,mod-2);}
const int maxn=(1<<21);
namespace fft{
int proot=step(3,7*17*4);
int prekw[maxn];
bool isprek=false;
void prek(){
    if(isprek)return;
    isprek=true;
    prekw[0]=1;
    for(int i=1;i<maxn;i++){
        prekw[i]=mul(prekw[i-1],proot);
    }
}
void fft(vector<int>&a,bool invert){

    prek();

    int n=a.size();
    int j=0;
    for(int i=1;i<n;i++){
        int bit=n>>1;
        for(;bit&j;bit>>=1)j^=bit;
        j^=bit;
        if(i<j)swap(a[i],a[j]);
    }

    for(int len=2;len<=n;len<<=1){
        int hlen=len>>1;
        for(int i=0;i<n;i+=len){
            int curr=0;
            int d=maxn/len;
            if(invert)d=maxn-d;
            for(int j=0;j<hlen;j++){
                int pom1=a[i+j];
                int pom2=mul(a[i+j+hlen],prekw[curr]);

                a[i+j]=add(pom1,pom2);
                a[i+j+hlen]=sub(pom1,pom2);

                curr+=d;
                if(curr>=maxn)curr-=maxn;
            }
        }
    }

    if(invert){
        int invn=invv(n);
        for(int i=0;i<n;i++)a[i]=mul(a[i],invn);
    }

}

}

void print(vector<int> a){
	printf("[ ");
	for(int i=0;i<sz(a);i++){
		printf("%i",a[i]);
		if(i==sz(a)-1)printf(" ]");
		else printf(", ");
	}
}
void move(vector<int> &v,bool smer){
	v.resize(maxn);
	fft::fft(v,smer);
}
vector<int> mul(vector<int> a,vector<int> b){
    for(int i=0;i<sz(a);i++)a[i]=mul(a[i],b[i]);
    return a;
}
vector<int> add(vector<int> a,vector<int> b){
	for(int i=0;i<sz(a);i++)a[i]=add(a[i],b[i]);
    return a;
}
int dvxconst=invv(step(3,7*17*4));
vector<int> divx(vector<int> a){
	for(int i=0;i<sz(a);i++)a[i]=mul(a[i],dvxconst);
	return a;
}
int main()
{
	int k;
	cin >> k;
	vector<int> p0={0,1},p1={0,1};
	vector<int> f0={0,1},f1={0,0},f2={0,0};
	vector<int> np0,np1,nf0,nf1,nf2;
	vector<int> divp0,divp1;
	vector<int> v11={1,1};
	vector<int> v01m1={0,1,-1};
	vector<int> v0m1={0,-1};
	vector<int> v00m1={0,0,-1};
	vector<int> v2={2};
	int inv2=invv(2);
	vector<int> vinv2={inv2};
	vector<int> fl={2};
	
	move(p0,0);
	move(p1,0);
	move(f0,0);
	move(f1,0);
	move(f2,0);
	move(v11,0);
	move(v01m1,0);
	move(v0m1,0);
	move(v00m1,0);
	move(v2,0);
	move(vinv2,0);
	move(fl,0);
	
	auto trans1=[&](){
		np0=add(mul(p0,v11),v01m1);
		np1=mul(p1,v11);
		nf0=add(mul(p0,p0),add(mul(f0,v2),v01m1));
		nf1=add(mul(mul(p0,p1),v2),mul(f1,v2));
		nf2=add(mul(p1,p1),mul(f2,v2));
		fl=add(fl,fl);
		p0=np0;p1=np1;f0=nf0;f1=nf1;f2=nf2;
	};
	auto trans2=[&](){
		divp0=add(divx(p0),add(p0,v0m1));
		divp1=divx(p1);
		np0=add(add(mul(p0,divp1),p0), mul(p1,add(p0,v0m1)));
		
		divp1=add(divp1,p1);
		np1=mul(p1,divp1);
		
		nf0=add(f0,
		add(mul(f1,divp0),
		add(mul(f2,mul(divp0,divp0)),
		add(mul(f0,fl),
		mul(add(mul(p0,p0),v00m1),mul(fl,vinv2))
		))));
		
		nf1=add(mul(f1,divp1),
		add(mul(mul(f2,v2),mul(divp0,divp1)),
		add(mul(f1,fl),
		mul(mul(p0,p1),fl)
		)));
		
		nf2=add(mul(f2,mul(divp1,divp1)),
		add(mul(f2,fl),
		mul(mul(p1,p1),mul(fl,vinv2))
		));
		
		p0=np0;p1=np1;f0=nf0;f1=nf1;f2=nf2;
		fl=mul(fl,fl);
	};
	function<void(int)> rec=[&](int t){
		if(t==1)return;
		if(t%2==0){
			rec(t/2);
			trans2();
		}
		else{
			rec(t/2);
			trans2();
			//printf("p0: ");print(p0);printf("\np1: ");print(p1);printf("\nf0: ");print(f0);printf("\nf1: ");print(f1);printf("\nf2: ");print(f2);printf("\n");
			trans1();
		}
	};
	rec(k);
	/*for(int i=1;i<k;i++){
		trans1();
		//printf("p0: ");print(p0);printf("\np1: ");print(p1);printf("\nf0: ");print(f0);printf("\nf1: ");print(f1);printf("\nf2: ");print(f2);printf("\n");
	}*/
	move(f0,1);
	move(f1,1);
	move(f2,1);
	move(fl,1);
	for(int i=0;i<2*k-2;i++){
		int x=add(f0[i+1],add(f1[i+1],f2[i+1]));
		if(i==0)x=add(x,fl[0]);
		printf("%i ",x);
	}
	printf("\n");
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1850ms
memory: 249044kb

input:

2

output:

7 3 

result:

ok 2 tokens

Test #2:

score: -100
Time Limit Exceeded

input:

3

output:

15 6 717602865 526190916 

result: