zoukankan      html  css  js  c++  java
  • [cf1392I]Kevin and Grid

    令$v$为点数(有公共点的格子中存在红/蓝色)、$e$为边数(有公共边的格子中存在红/蓝色)、$f$为以此法(即仅考虑这些点和边)所分割出的区域数(包括外面)、$s$为连通块个数,将欧拉定理简单扩展,可以得到$v-e+f=s+1$

    (对于样例1中红点部分,有$v=16$、$e=24$、$f=10$、$s=1$;对于蓝点部分,有$v=36$、$e=52$、$f=19$、$s=2$)

    令$s_{r/b}'$表示红/蓝色中不在边界上的连通块个数,那么答案为$(v_{b}-e_{b}+v_{r}-e_{r})+(f_{b}-f_{r}+s'_{b}-s'_{r})$,令$f'_{b}=f_{b}-s'_{r}$,$f'_{r/b}$即为红/蓝色的格子数量+1(每一个在其内部的另一种颜色的连通块必然恰好对应一个不是红色格子或最外部的区域)

    因此,即求出$v/e/f'_{r/b}$,以$f'_{r}$为例,令$f(x)=sum_{i=1}^{n}x^{a_{i}}sum_{i=1}^{m}x^{b_{i}}$,则$f(x)=sum_{i=k}^{infty}f(x)[i]$($f(x)[i]$表示$f(x)$的$x^{i}$项系数),用fft计算即可(需要13次fft)

     1 #include<bits/stdc++.h>
     2 #include<complex.h>
     3 using namespace std;
     4 #define N (1<<18)
     5 #define PI acos(-1.0)
     6 #define ll long long
     7 #define cp complex<double>
     8 struct pol{
     9     cp a[N];
    10 }x[3],y[3],z;
    11 pair<int,int>qu[N];
    12 int n,m,q,a[N],b[N],rev[N];
    13 ll s[2][N],ans[N];
    14 void fft(pol &a,int p){
    15     for(int i=0;i<N;i++)
    16         if (rev[i]<i)swap(a.a[i],a.a[rev[i]]);
    17     for(int i=2;i<=N;i*=2){
    18         cp s=cp(cos(2*PI/i),sin(2*PI/i));
    19         if (p)s=conj(s);
    20         for(int j=0;j<N;j+=i){
    21             cp ss=cp(1,0);
    22             for(int k=0;k<(i>>1);k++,ss*=s){
    23                 cp x=ss*a.a[j+k+(i>>1)];
    24                 a.a[j+k+(i>>1)]=a.a[j+k]-x;
    25                 a.a[j+k]+=x;
    26             }
    27         }
    28     }
    29 }
    30 void add(pol &a,int x,int y){
    31     fft(a,-1);
    32     for(int i=0;i<N;i++){
    33         s[0][i]+=x*floor(a.a[i].real()/N+0.5);
    34         s[1][i]+=y*floor(a.a[i].real()/N+0.5);
    35     }
    36 }
    37 void init(){
    38     for(int i=0;i<N;i++)rev[i]=(i&1)*(N/2)+(rev[i>>1]>>1);
    39     for(int i=1;i<=n;i++)x[0].a[a[i]]+=cp(1,0);
    40     for(int i=1;i<=m;i++)y[0].a[b[i]]+=cp(1,0);
    41     for(int i=0;i<=n;i++)x[1].a[max(a[i],a[i+1])]+=cp(1,0);
    42     for(int i=0;i<=m;i++)y[1].a[max(b[i],b[i+1])]+=cp(1,0);
    43     a[0]=a[n+1]=b[0]=b[m+1]=0x3f3f3f3f;
    44     for(int i=0;i<=n;i++)x[2].a[min(a[i],a[i+1])]+=cp(1,0);
    45     for(int i=0;i<=m;i++)y[2].a[min(b[i],b[i+1])]+=cp(1,0);
    46     for(int i=0;i<3;i++){
    47         fft(x[i],0);
    48         fft(y[i],0);
    49     }
    50     for(int i=0;i<N;i++)z.a[i]=x[0].a[i]*y[0].a[i];
    51     add(z,1,1);
    52     for(int i=0;i<N;i++)z.a[i]=x[0].a[i]*y[1].a[i];
    53     add(z,-1,0);
    54     for(int i=0;i<N;i++)z.a[i]=x[1].a[i]*y[0].a[i];
    55     add(z,-1,0);
    56     for(int i=0;i<N;i++)z.a[i]=x[1].a[i]*y[1].a[i];
    57     add(z,1,0);
    58     for(int i=0;i<N;i++)z.a[i]=x[0].a[i]*y[2].a[i];
    59     add(z,0,-1);
    60     for(int i=0;i<N;i++)z.a[i]=x[2].a[i]*y[0].a[i];
    61     add(z,0,-1);
    62     for(int i=0;i<N;i++)z.a[i]=x[2].a[i]*y[2].a[i];
    63     add(z,0,1);
    64 }
    65 int main(){
    66     scanf("%d%d%d",&n,&m,&q);
    67     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    68     for(int i=1;i<=m;i++)scanf("%d",&b[i]);
    69     init();
    70     for(int i=1;i<=q;i++){
    71         scanf("%d",&qu[i].first);
    72         qu[i].second=i;
    73     }
    74     sort(qu+1,qu+q+1);
    75     ll k=0;
    76     for(int i=q,j=N-1;i;i--){
    77         while (qu[i].first<=j)k+=s[0][j--];
    78         ans[qu[i].second]=k;
    79     }
    80     k=0;
    81     for(int i=1,j=0;i<=q;i++){
    82         while (j<qu[i].first)k+=s[1][j++];
    83         ans[qu[i].second]-=k;
    84     }
    85     for(int i=1;i<=q;i++)printf("%lld
    ",ans[i]);
    86 }
    View Code
  • 相关阅读:
    Java中怎样由枚举常量的ordinal值获得枚举常量对象
    深入了解泛型
    艰苦的RAW格式数据恢复之旅
    eclipse 代码清理 代码格式化 代码凝视
    应用策略设计模式
    JavaEE SSH集成框架(两) struts2 本地加载dtd文件,action组态
    关闭表空间的热备份实例重新启动重现错误和解决
    CF 148D. Bag of mice (可能性DP)
    C++ Primer 学习笔记_45_STL实践与分析(19)--建筑常规算法
    工作的几点思考
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13763974.html
Copyright © 2011-2022 走看看