zoukankan      html  css  js  c++  java
  • P6913 [ICPC2015 WF]Tile Cutting

    P6913 [ICPC2015 WF]Tile Cutting

    我居然只会打NTT就做出WF的多项式题了。会做这些题有什么用哦,CSP又发挥不出来/ll

    变量标在图上了,有4个,设平行四边形的面积为 (w)

    那么

    [w=xy-ab-(x-a)(y-b)\ xy-ab-xy+ay+xb-ab=w\ ay+xb-2ab=w\ a(y-b)+b(x-a)=w\ alphaeta+gamma heta=w\ ]

    最后一步可以直接替换,并不需要多余的限制条件。

    因为 (a,b) 均与 (x,y) 无关,所以 (x-a,y-b) 的大小均任意。

    (g_i) 表示 (xy=i)((x,y)) 个数。

    那么 (f(w)=sum_{i=1}^{w-1}g_i*g_{w-i}) 直接卷积就好了。

    (g_i) 直接筛就是 (O(nln n)) ,线性筛因子个数也行,只是没必要,这里的常数和 (NTT) 比小到哪里去都不知道了。

    答案上界是要估算一下的。

    (g_i) 最大是 (200) ,那么 (g_ig_jle 40000) ,那么 (f(w)le 40000*500000=2e10) ,事实上大部分 (g_i) 远达不到 (200)毛估估 炸不掉 (998244353) ,拿NTT卷即可。

    实测最大 160474864

    至于要求区间最大值,随你怎么求了。

    居然和El跑的一样快?!我和Eltietie

    为啥yhx跑的那么快啊,被吊打了/ll

    这道题的通过率在我做完之后居然还是100%,不可思议。

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mkp(x,y) make_pair(x,y)
    #define pb(x) push_back(x)
    typedef long long LL;
    typedef double db;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    #define N 500005
    #define M (N<<2)
    #define C 500000
    #define mod 998244353
    int qpow(int n,int k){int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
    int a[M],rev[M],lg,lim;
    int id[20][N],mx[20][N],lg2[N],pw2[40];
    int n;
    void init_poly(int n){
    	for(lim=1,lg=0;lim<n;lim<<=1,++lg);
    	for(int i=0;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
    }
    void fmod(int&x){x-=mod,x+=x>>31&mod;}
    void NTT(int*a,int g,int op=0){
    	for(int i=0;i<lim;++i)
    		if(i>rev[i])swap(a[i],a[rev[i]]);
    	for(int i=1;i<lim;i<<=1){
    		int wn=qpow(g,(mod-1)/(i<<1));
    		for(int j=0;j<lim;j+=i<<1){
    			int w0=1;
    			for(int k=0;k<i;++k,w0=1ll*w0*wn%mod){
    				int X=a[j+k],Y=1ll*w0*a[i+j+k]%mod;
    				a[j+k]=(X+Y)%mod,a[i+j+k]=(X-Y+mod)%mod;
    			}
    		}
    	}
    	if(!op)return;int ilim=qpow(lim,mod-2);
    	for(int i=0;i<lim;++i)a[i]=1ll*a[i]*ilim%mod;
    }
    void init_ST(const int&n){
    	lg2[0]=-1;for(int i=1;i<=n;++i)lg2[i]=lg2[i>>1]+1;
    	pw2[0]=1;for(int i=1;i<=20;++i)pw2[i]=pw2[i-1]<<1;
    	for(int i=1;i<=n;++i)mx[0][i]=a[i],id[0][i]=i;
    	for(int i=1;i<=lg2[n];++i)
    		for(int j=1;j+pw2[i]-1<=n;++j){
    			int t=j+pw2[i-1];
    			if(mx[i-1][j]>=mx[i-1][t])mx[i][j]=mx[i-1][j],id[i][j]=id[i-1][j];
    			else mx[i][j]=mx[i-1][t],id[i][j]=id[i-1][t];
    		}
    }
    void ask(int l,int r){
    	int x=lg2[r-l+1],t=r-pw2[x]+1;
    	if(mx[x][l]>=mx[x][t])printf("%d %d
    ",id[x][l],mx[x][l]);
    	else printf("%d %d
    ",id[x][t],mx[x][t]);
    }
    signed main(){
    	for(int i=1;i<=C;++i)
    		for(int j=1;i*j<=C;++j)
    			++a[i*j];
    	init_poly(C<<1),NTT(a,3);
    	for(int i=0;i<lim;++i)a[i]=1ll*a[i]*a[i]%mod;
    	NTT(a,qpow(3,mod-2),1);
    	init_ST(C);
    	n=read();
    	while(n--){
    		int l=read(),r=read();
    		ask(l,r);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Linux安装zookeeper以及部署dubbo-admin
    springboot+layui+mybatis-plus的批量删除(批量修改)
    springboot打包jar与war包
    drf-books系列接口作业和分页器
    drf-过滤排序异常处理封装Response对象
    drf-认证权限频率
    drf-路由组件
    视图组件
    请求和响应
    Serializer和ModelSerializer
  • 原文地址:https://www.cnblogs.com/zzctommy/p/13985317.html
Copyright © 2011-2022 走看看