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]);}}

  • 相关阅读:
    Leetcode Excel Sheet Column Number
    AlgorithmsI PA2: Randomized Queues and Deques Subset
    AlgorithmsI PA2: Randomized Queues and Deques RandomizedQueue
    AlgorithmsI PA2: Randomized Queues and Deques Deque
    AlgorithmsI Programming Assignment 1: PercolationStats.java
    hdu多校第四场 1003 (hdu6616) Divide the Stones 机智题
    hdu多校第四场 1007 (hdu6620) Just an Old Puzzle 逆序对
    hdu多校第四场1001 (hdu6614) AND Minimum Spanning Tree 签到
    hdu多校第三场 1007 (hdu6609) Find the answer 线段树
    hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8682522.html
Copyright © 2011-2022 走看看