* ! Daniel13265的公开赛
Daniel的卡常&数学赛
\[M=(ap+bq+cr-ds)^2(-ap+bp+cs+dr)^2
\]
构造复数\(A=a+bi,x=p-qi,B=c+di,y=r+si\)则\(M=|Ax+By|^2\)(|为模长)

复数扩欧即可
复数取模相关:

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
struct complx{
int x,y;
complx(int xx=0,int yy=0):x(xx),y(yy){}
inline int len(){return x*x+y*y;}
inline operator bool()const{return x||y;}
inline complx operator +(const complx& a)const{return complx(x+a.x,y+a.y);}
inline complx operator -(const complx& a)const{return complx(x-a.x,y-a.y);}
inline complx operator *(const complx& a)const{return complx(x*a.x-y*a.y,x*a.y+y*a.x);}
inline complx operator /(const complx& a)const{
static int t;t=a.x*a.x+a.y*a.y;
return complx(round((double)(x*a.x+y*a.y)/t),round((double)(y*a.x-x*a.y)/t));//?round
}
friend inline complx operator %(const complx& a,const complx& b){return a-a/b*b;}
};
void exgcd(complx a,complx b,complx& x,complx& y){
if(b){
exgcd(b,a%b,y,x);
y=y-a/b*x;
}
else{x=complx(1,0);y=complx(0,0);}
}
signed main(){
int a=read(),b=read(),c=read(),d=read();
complx A(a,b),B(c,d),x,y;
exgcd(A,B,x,y);
cout<<x.x<<" "<<-x.y<<" "<<y.x<<" "<<y.y<<" "<<(A*x+B*y).len();
return (0-0);
}
题意大概像卷积\(c_n=\sum_{i+j=n}min(a_i,b_j)\)
于是我们一位一位枚举就变成了卷积
\[c_n=\sum_{k=1}^m\sum_{i+j=n}[a_i\ge k][b_i\ge k]
\]
但是复杂度爆表
于是分块优化,大于\(t\)的最多有\(min(\frac nt,m)\)个,暴力算,小于\(t\)的用卷积
时间复杂度\(O(tm\log m+(\frac nt)^2)\),当\(t=\sqrt[3]{\frac{n^2}{m\log m}}\)时最小\(O((nm\log m)^{\frac23})\),由于卷积常数较大,\(t\)小于该值时运行效率更高
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
#define ll long long
const int mod=998244353,g=3;
inline int ksm(int x,int r){
int ret=1;
for(int i=0;(1ll<<i)<=r;i++){
if((r>>i)&1)ret=(ll)ret*x%mod;
x=(ll)x*x%mod;
}
return ret;
}
const int N=1e5+4;
int rev[N<<2];
inline void NTT(int *a,int len,int lim,int fl){
for(int i=0;i<len;i++){
rev[i]=(rev[i>>1]>>1)|((i&1)<<lim-1);
if(i<rev[i])swap(a[i],a[rev[i]]);
}
for(int mid=1,tmp,x,u,v;mid<len;mid<<=1){
tmp=ksm(g,(mod-1)/(mid<<1));
if(fl==-1)tmp=ksm(tmp,mod-2);
for(int i=0;i<len;i+=(mid<<1)){
x=1;
for(int j=0;j<mid;j++,x=(ll)x*tmp%mod){
u=a[i+j];v=(ll)x*a[i+j+mid]%mod;
a[i+j]=(u+v)%mod;a[i+j+mid]=(u-v+mod)%mod;
}
}
}
if(fl==-1)for(int i=0,tmp=ksm(len,mod-2);i<len;i++)
a[i]=(ll)a[i]*tmp%mod;
}
int n,m,t,lim,len=1,ans,tot,a[N<<2],b[N],c[N],f[N<<1];
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)c[read()]++;
t=sqrt(sqrt((ll)n*n/m));//数据分治
while(len<=(m<<1)){len<<=1;lim++;}
for(int i=1;i<=t;i++){
for(int j=1;j<=m;j++){
if(c[j]>=i)a[j]=1;
else a[j]=0;
}
a[0]=0;
for(int j=m+1;j<len;j++)a[j]=0;
NTT(a,len,lim,1);
for(int j=0;j<len;j++)a[j]=(ll)a[j]*a[j]%mod;
NTT(a,len,lim,-1);
for(int j=1;j<=(m<<1);j++)f[j]+=a[j];
}
for(int i=1;i<=m;i++){
c[i]-=t;
if(c[i]>0){
c[++tot]=c[i];
b[tot]=i;
}
}
for(int i=1;i<=tot;i++)
for(int j=1;j<=tot;j++)
f[b[i]+b[j]]+=min(c[i],c[j]);
for(int i=1;i<=(m<<1);i++)
if(f[i]>f[ans])ans=i;
cout<<f[ans]/2<<" "<<ans;
return (0-0);
}
权值线段树
不过是\(w\)叉树,非叶子节点用二进制压位存储子节点代表的区间内有无非零值
7,8询问时从下往上找
这样123478操作时间复杂度\(O(log_wn)\),56操作时间复杂度\(O(1)\)
空间复杂度\(\sum_{k=1}^{log_wn}O(\frac n{w^k})=O(\frac nk)\)
code:(待更)
作者:starusc
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号