zoukankan      html  css  js  c++  java
  • bzoj 4827 礼物

    题目大意:

    两个环之间的差异度定义为$sum_{i=1}^n (a_i-b_i)^2$

    可以进行两种操作 对其中一个环加上$c,m geq c geq 0$与对环进行旋转

    思路:

    对其中一个环加上非负整数相当于对于一个环加$c,cin[-m,m]$

    则设a环转了$j$,则差异度为$sum_{i=1}^n (a_{i+j}+c-b_i)^2$

    $sum_{i=1}^n ({a_i}^2+{b_i}^2+c^2+2*c*(a_i-b_i)-2*a_{i+j}*b_i)$

    由于$c$的范围很小,枚举$c$后除了最后一项都是可以可以快速算出来的

    发现对于每一个$j$,$a$与$b$的下标之差为$j$考虑把其中一个数组倒序

    则转化为卷积形式 使用$fft$

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 200100
    15 #define MOD 998244353
    16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    18 #define ren for(register int i=fst[x];i;i=nxt[i])
    19 #define pb(i,x) vec[i].push_back(x)
    20 #define pls(a,b) (a+b)%MOD
    21 #define mns(a,b) (a-b+MOD)%MOD
    22 #define mul(a,b) (1LL*(a)*(b))%MOD
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    28     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,rev[MAXN],l2[MAXN],a1[MAXN],a2[MAXN];
    32 const db pi=acos(-1);db sum,ans=inf;
    33 struct Cd{db x,y;Cd(db X=0,db Y=0) {x=X,y=Y;}}a[MAXN],b[MAXN];
    34 Cd operator + (Cd a,Cd b) {return (Cd){a.x+b.x,a.y+b.y};}
    35 Cd operator - (Cd a,Cd b) {return (Cd){a.x-b.x,a.y-b.y};}
    36 Cd operator * (Cd a,Cd b) {return (Cd){a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y};}
    37 int q_pow(int x,int t,int res=1)
    38 {
    39     for(;t;t>>=1,x=mul(x,x))
    40         if(t&1) res=mul(res,x);
    41 }
    42 void fft(Cd *a,int n,int f)
    43 {
    44     rep(i,0,n-1) if(i<rev[i]) swap(a[i],a[rev[i]]);
    45     for(int i=1;i<n;i<<=1)
    46     {
    47         Cd wn(cos(pi/i),f*sin(pi/i));
    48         for(int j=0;j<n;j+=i<<1)
    49         {
    50             Cd w(1,0),x,y;
    51             for(int k=0;k<i;k++,w=w*wn)
    52                 x=a[k+j],y=a[i+k+j]*w,a[k+j]=x+y,a[i+k+j]=x-y;
    53         }
    54     }
    55     if(f==1) return ;rep(i,0,n-1) a[i].x/=(db)n;
    56 }
    57 void solve(Cd *a,Cd *b,int sum)
    58 {
    59     int t=l2[sum]+1,lmt=1<<t;
    60     rep(i,0,lmt-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(t-1));
    61     fft(a,lmt,1);fft(b,lmt,1);rep(i,0,lmt-1) a[i]=a[i]*b[i];
    62     fft(a,lmt,-1);
    63 }
    64 int main()
    65 {
    66     n=read(),m=read();int lmt,t;
    67     rep(i,0,n-1) a1[i]=read();rep(i,0,n-1) a2[i]=read();
    68     l2[0]=-1;rep(i,1,n<<2) l2[i]=l2[i>>1]+1;lmt=1<<l2[n<<1]+1;
    69     rep(i,0,n-1) a[i].x=a1[i],sum+=a1[i]*a1[i]+a2[i]*a2[i],t+=2*(a1[i]-a2[i]);
    70     rep(i,0,n-1) a[i+n].x=a[i].x,b[i].x=a2[n-1-i];
    71     solve(a,b,n<<1);
    72     rep(x,-m,m)    rep(i,n-1,2*n-1) ans=min(ans,sum-t*x+n*x*x-2*round(a[i].x));
    73     printf("%.0lf
    ",ans);
    74 }
    View Code
  • 相关阅读:
    P1903 [国家集训队]数颜色 / 维护队列 莫对算法
    P1016 旅行家的预算 模拟 贪心
    P3948 数据结构 差分数组
    乘法逆元 模板
    二分法 最大化平均值
    HDU5213 Lucky 莫队算法 容斥定理
    P1083 借教室 差分数组
    发布订阅、redis的配置文件、redis的主从、redis的持久化、
    nosql、redis、性能测试、命令相关、redis的数据类型string、list、hash、set、zset、
    nginx的日志、禁止访问、反向代理、权重、nginx location匹配规则、location分离、WSGI、
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10521136.html
Copyright © 2011-2022 走看看