zoukankan      html  css  js  c++  java
  • bzoj 4836 [Lydsy1704月赛]二元运算 分治FFT+生成函数

    [Lydsy1704月赛]二元运算

    Time Limit: 8 Sec  Memory Limit: 128 MB
    Submit: 577  Solved: 201
    [Submit][Status][Discuss]

    Description

    定义二元运算 opt 满足
     
    现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问。每次询问给定一个数字 c 
    你需要求出有多少对 (i, j) 使得 a_i  opt b_j=c 。
     
     
     

    Input

    第一行是一个整数 T (1≤T≤10) ,表示测试数据的组数。
    对于每组测试数据:
    第一行是三个整数 n,m,q (1≤n,m,q≤50000) 。
    第二行是 n 个整数,表示 a_1,a_2,?,a_n (0≤a_1,a_2,?,a_n≤50000) 。
    第三行是 m 个整数,表示 b_1,b_2,?,b_m (0≤b_1,b_2,?,b_m≤50000) 。
    第四行是 q 个整数,第 i 个整数 c_i (0≤c_i≤100000) 表示第 i 次查询的数。
     
     

    Output

    对于每次查询,输出一行,包含一个整数,表示满足条件的 (i, j) 对的个数。

     
     

    Sample Input

    2
    2 1 5
    1 3
    2
    1 2 3 4 5
    2 2 5
    1 3
    2 4
    1 2 3 4 5

    Sample Output

    1
    0
    1
    0
    0
    1
    0
    1
    0
    1

    HINT

     

    这道题就是分治fft的生成函数题,加法应该很好办,但是减法怎么办,就是将其变成加法就可以了。

    减法的时候,对于x-y,变成x-mid-1,mid-y,这样就相加就变成了x-y-1,最后把1加上去就可以了。

      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<iostream>
      6 
      7 #define pi acos(-1)
      8 #define ll long long
      9 #define N 100007
     10 using namespace std;
     11 inline int read()
     12 {
     13     int x=0,f=1;char ch=getchar();
     14     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     15     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 
     19 int n,m,q,mx;
     20 int a[N],b[N],rev[N<<1];
     21 ll ans[N];
     22 struct comp
     23 {
     24     double r,v;
     25     comp(){r=v=0.0;}
     26     comp(double x,double y){r=x,v=y;}
     27     void init(){r=v=0.0;}
     28     friend inline comp operator+(comp x,comp y){return comp(x.r+y.r,x.v+y.v);}
     29     friend inline comp operator-(comp x,comp y){return comp(x.r-y.r,x.v-y.v);}
     30     friend inline comp operator*(comp x,comp y){return comp(x.r*y.r-x.v*y.v,x.r*y.v+x.v*y.r);}
     31     friend inline comp operator/(comp x,int y){return comp(x.r/y,x.v/y);}
     32 }c[N<<1],d[N<<1];
     33 
     34 void FFT(comp *a,int flag,int num)
     35 {
     36     for (int i=0;i<num;i++)
     37         if (i<rev[i]) swap(a[i],a[rev[i]]);
     38     for (int i=1;i<num;i<<=1)
     39     {
     40         comp wn=comp(cos(pi/i),flag*sin(pi/i));
     41         for (int j=0;j<num;j+=(i<<1))
     42         {
     43             comp w=comp(1,0);
     44             for (int k=0;k<i;k++,w=w*wn)
     45             {
     46                 comp x=a[j+k],y=w*a[i+j+k];
     47                 a[j+k]=x+y,a[j+k+i]=x-y;
     48             }
     49         }
     50     }
     51     if (flag==-1) for (int i=0;i<num;i++) a[i].r=a[i].r/num;
     52 }
     53 void CDQ(int l,int r)
     54 {
     55     if (l==r)
     56     {
     57         ans[0]+=(ll)a[l]*b[l];
     58         return;
     59     }
     60     int mid=(l+r)>>1,num,up=r-l+1,L=0;
     61     for (num=1;num<=up;num<<=1,L++);if (L) L--;
     62     for (int i=0;i<num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
     63     
     64     memset(c,0,sizeof(c[0])*num),memset(d,0,sizeof(d[0])*num);
     65     for (int i=l;i<=mid;i++) c[i-l].r=a[i];
     66     for (int i=mid+1;i<=r;i++) d[i-mid-1].r=b[i];
     67     FFT(c,1,num),FFT(d,1,num);
     68     for (int i=0;i<num;i++) c[i]=c[i]*d[i];
     69     FFT(c,-1,num);
     70     for (int i=0;i<num;i++) ans[i+l+mid+1]+=(ll)(c[i].r+0.5);
     71     
     72     memset(c,0,sizeof(c[0])*num),memset(d,0,sizeof(d[0])*num);
     73     for (int i=mid+1;i<=r;i++) c[i-mid-1].r=a[i];
     74     for (int i=l;i<=mid;i++) d[mid-i].r=b[i];
     75     FFT(c,1,num),FFT(d,1,num);
     76     for (int i=0;i<num;i++) c[i]=c[i]*d[i];
     77     FFT(c,-1,num);
     78     for (int i=0;i<num;i++) ans[i+1]+=(ll)(c[i].r+0.5);
     79     
     80     CDQ(l,mid),CDQ(mid+1,r);
     81 }
     82 int main()
     83 {
     84     int T=read();
     85     while(T--)
     86     {
     87         n=read(),m=read(),q=read();
     88         memset(a,0,sizeof(a)),memset(b,0,sizeof(b)),memset(ans,0,sizeof(ans));
     89         for (int i=1;i<=n;i++)
     90         {
     91             int x=read();
     92             a[x]++,mx=max(mx,x);
     93         }
     94         for (int i=1;i<=m;i++)
     95         {
     96             int x=read();
     97             b[x]++,mx=max(mx,x);
     98         }
     99         CDQ(0,mx);
    100         for (int i=1;i<=q;i++)
    101             printf("%lld
    ",ans[read()]);
    102     }
    103 }
     

    #include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<cstdio>
    #define pi acos(-1)#define N 600007using namespace std;inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
    int R,C,H,W,num,L;int rev[N],a[507][507],b[507][507];struct comp{double r,v;comp(){r=v=0.0;}comp(double x,double y){r=x,v=y;}void init(){r=v=0.0;}friend inline comp operator+(comp x,comp y){return comp(x.r+y.r,x.v+y.v);}friend inline comp operator-(comp x,comp y){return comp(x.r-y.r,x.v-y.v);}friend inline comp operator*(comp x,comp y){return comp(x.r*y.r-x.v*y.v,x.r*y.v+x.v*y.r);}friend inline comp operator/(comp x,int y){return comp(x.r/y,x.v/y);}}a1[N],b1[N],a2[N],b2[N],c[N];char ch[507],T[507][507];
    void FFT(comp *a,int flag){for (int i=0;i<num;i++)if (i<rev[i]) swap(a[i],a[rev[i]]);for (int i=1;i<num;i<<=1){comp wn=comp(cos(pi/i),flag*sin(pi/i));for (int j=0;j<num;j+=(i<<1)){comp w=comp(1,0);for (int k=0;k<i;k++,w=w*wn){comp x=a[j+k],y=w*a[j+k+i];a[j+k]=x+y,a[j+k+i]=x-y;}}}if (flag==-1) for (int i=0;i<num;i++) a[i].r=a[i].r/num;}int main(){R=read(),C=read();for (int i=0;i<R;i++){scanf("%s",ch);for (int j=0;j<C;j++){if (ch[j]=='G') a1[i*C+j]=comp(1,0);else b1[i*C+j]=comp(1,0);}}for (num=1;num<=R*C*2;num<<=1,L++);if (L) L--;for (int i=0;i<num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);FFT(a1,1),FFT(b1,1);int Total=read();for (int Case=1;Case<=Total;Case++){H=read(),W=read(),memset(a,0,sizeof(a)),memset(b,0,sizeof(b));for (int i=0;i<num;i++)a2[i].init(),b2[i].init();for (int i=0;i<H;i++)scanf("%s",T[i]);for (int i=0;i<H;i++)for (int j=0;j<W;j++)if (T[i][j]=='G') a2[R*C-1-i*C-j]=comp(1,0);else b2[R*C-1-i*C-j]=comp(1,0);FFT(a2,1),FFT(b2,1);for (int i=0;i<num;i++)a2[i]=a1[i]*a2[i],b2[i]=b1[i]*b2[i];FFT(a2,-1),FFT(b2,-1);for (int i=0;i<R-H;i++)for (int j=0;j<C-W;j++)a[i][j]=(int)(a2[i*C+j+R*C-1].r+0.5),b[i][j]=(int)(b2[i*C+j+R*C-1].r+0.5);int x,y;x=y=0;for (int i=0;i<R-H;i++)for (int j=0;j<=C-W;j++)if (a[i][j]+b[i][j]>a[x][y]+b[x][y]) x=i,y=j;printf("Case #%d: %d %d %d %d ",Case,x+1,y+1,a[x][y],b[x][y]);}}

  • 相关阅读:
    分享个好的笔记软件:为知笔记
    Mysql的一些常用方法
    从0到1体验Jenkins+Docker+Git+Registry实现CI自动化发布
    【超级详细】使用 PXE+Kickstart 实现无人值守批量部署系统
    Linux杀不死的进程之CPU使用率700%
    Hadoop 从节点的 NodeManager 无法启动
    Phoenix 无法启动报错: java.net.BindException: Address already in use
    CentOS7 配置 SSH监听多个端口方法
    Linux CentOS 防止SSH暴力破解
    Windows出现“引用账户被锁定,且暂时无法登录”解决方法
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8682522.html
Copyright © 2011-2022 走看看