【bzoj3771】【xsy1728】

题意

求\(\sum_{i}[a_i=S]+\sum_{i<j}[a_i+a_j=S]+\sum_{i<j<k}[a_i+a_j+a_k=S]\)

\(n\leq 30000\),\(a_i\leq 40000\)

分析

容斥+FFT。

主要展现一些通过翻阅众多题解,得到的一些启示。

①把IDFT的除法放在内部。

void FFT(CP a[S],int len,int kd) {
    //...
    if (kd==-1) {
        rep(i,0,len-1)
            a[i].x/=len;
    }
}

②变量声明的合理放置

int lenA,lenB,lenR;
int bit,len; int rev[S];
struct CP {
    double x,y;
    CP (double _x=0,double _y=0) {
        x=_x,y=_y;
    }
    friend CP operator + (CP a,CP b) {
        return CP(a.x+b.x,a.y+b.y);
    }
    friend CP operator - (CP a,CP b) {
        return CP(a.x-b.x,a.y-b.y);
    }
    friend CP operator * (CP a,CP b) {
        return CP(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    }
}a[S],b[S],r[S],tmp[S];

③良好的封闭性Mut(a,lenA,b,lenB,r,lenR)

void Mut(CP a[S],int lenA,CP b[S],int lenB,CP r[S],int &lenR) {
    fill(r,r+S,0);
    lenR=lenA+lenB;

    len=1,bit=0;
    while (len<=lenA||len<=lenB)
        len<<=1,bit++;
    len<<=1,bit++;

    memset(rev,0,sizeof rev);
    rep(i,0,len-1) {
        int x=0;
        rep(j,0,bit-1)
            if (i>>j&1)
                x+=(1<<(bit-1-j));
        rev[i]=x;
    }

    FFT(a,len,1);
    FFT(b,len,1);
    rep(i,0,len-1) r[i]=a[i]*b[i];
    FFT(r,len,-1);
}
LL Trans(CP a) {
    return (LL)(a.x+0.5);
}

注意要使用Fill而不能使用memset。

④生成函数对数组的初始化

由于大量使用了相同的生成函数,所以写作一个过程。

int cmp(double x) {
    if (fabs(x)<EPS) return 0;
    return x<0?-1:1;
}
void IA(CP *a,int &lenA) {
    fill(a,a+S,0);
    rep(i,1,n) a[w[i]].x+=1.0;

    lenA=C1;
    while (lenA>=0&&!cmp(a[lenA].x))
        lenA--;
}
void IA2(CP a[S],int &lenA) {
    fill(a,a+S,0);
    rep(i,1,n) a[w[i]+w[i]].x+=1.0;

    lenA=C2;
    while (lenA>=0&&!cmp(a[lenA].x))
        lenA--;
}
void IA3(CP a[S],int &lenA) {
    fill(a,a+S,0);
    rep(i,1,n) a[w[i]+w[i]+w[i]].x+=1.0;

    lenA=C3;
    while (lenA>=0&&!cmp(a[lenA].x))
        lenA--;
}

⑤生成函数支持加法的合并

写了199行。

然后看了一下别人的代码。

woc77行......

发现生成函数支持加法的合并。

所以先用生成函数算出所有情况,然后再一次转换回来就好了。

代码

初次的AC代码:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

typedef long long LL;

const int N=65536;
const int S=262144;
const double PI=M_PI;

const int C1=40000;
const int C2=80000;
const int C3=120000;

const double EPS=1e-8;

int n;
int w[N];

LL cnt[S];

LL c[S];
int lenA,lenB,lenR;

int bit,len; int rev[S];
struct CP {
    double x,y;
    CP (double _x=0,double _y=0) {
        x=_x,y=_y;
    }
    friend CP operator + (CP a,CP b) {
        return CP(a.x+b.x,a.y+b.y);
    }
    friend CP operator - (CP a,CP b) {
        return CP(a.x-b.x,a.y-b.y);
    }
    friend CP operator * (CP a,CP b) {
        return CP(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    }
}a[S],b[S],r[S],tmp[S];

int rd(void) {
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

void FFT(CP a[S],int len,int kd) {
    rep(i,0,len-1) tmp[i]=a[rev[i]];
    rep(i,0,len-1) a[i]=tmp[i];

    for (int i=2;i<=len;i<<=1) {
        CP wn(cos(2*PI/i),sin(kd*2*PI/i));
        for (int k=0;k<len;k+=i) {
            CP w(1,0);
            rep(j,0,i/2-1) {
                CP x=a[k+j],y=w*a[k+j+i/2];
                a[k+j]=x+y,a[k+j+i/2]=x-y;
                w=w*wn;
            }
        }
    }

    if (kd==-1) {
        rep(i,0,len-1)
            a[i].x/=len;
    }
}
void Mut(CP a[S],int lenA,CP b[S],int lenB,CP r[S],int &lenR) {
    fill(r,r+S,0);
    lenR=lenA+lenB;

    len=1,bit=0;
    while (len<=lenA||len<=lenB)
        len<<=1,bit++;
    len<<=1,bit++;

    memset(rev,0,sizeof rev);
    rep(i,0,len-1) {
        int x=0;
        rep(j,0,bit-1)
            if (i>>j&1)
                x+=(1<<(bit-1-j));
        rev[i]=x;
    }

    FFT(a,len,1);
    FFT(b,len,1);
    rep(i,0,len-1) r[i]=a[i]*b[i];
    FFT(r,len,-1);
}
LL Trans(CP a) {
    return (LL)(a.x+0.5);
}

int cmp(double x) {
    if (fabs(x)<EPS) return 0;
    return x<0?-1:1;
}
void IA(CP *a,int &lenA) {
    fill(a,a+S,0);
    rep(i,1,n) a[w[i]].x+=1.0;

    lenA=C1;
    while (lenA>=0&&!cmp(a[lenA].x))
        lenA--;
}
void IA2(CP a[S],int &lenA) {
    fill(a,a+S,0);
    rep(i,1,n) a[w[i]+w[i]].x+=1.0;

    lenA=C2;
    while (lenA>=0&&!cmp(a[lenA].x))
        lenA--;
}
void IA3(CP a[S],int &lenA) {
    fill(a,a+S,0);
    rep(i,1,n) a[w[i]+w[i]+w[i]].x+=1.0;

    lenA=C3;
    while (lenA>=0&&!cmp(a[lenA].x))
        lenA--;
}

void Init(void) {
    n=rd();
    rep(i,1,n) w[i]=rd();
}
void Solve1(void) {
    IA(a,lenA);
    rep(i,1,lenA) cnt[i]+=Trans(a[i]);
}
void Solve2(void) {
    memset(c,0,sizeof c);

    IA(a,lenA); IA(b,lenB);
    Mut(a,lenA,b,lenB,r,lenR);
    rep(i,0,lenR) c[i]+=Trans(r[i]);

    IA2(a,lenA);
    rep(i,0,lenA) c[i]-=Trans(a[i]);

    rep(i,0,S-1)
        c[i]>>=1;

    rep(i,0,S-1)
        cnt[i]+=c[i];
}
void Solve3(void) {
    memset(c,0,sizeof c);

    // \sum(x,y,z)
    IA(a,lenA); IA(b,lenB);
    Mut(a,lenA,b,lenB,r,lenR);
    IA(a,lenA);
    Mut(a,lenA,r,lenR,b,lenB);
    rep(i,0,lenB) c[i]+=Trans(b[i]);;

    // \sum(x,x,y)
    IA2(a,lenA); IA(b,lenB);
    Mut(a,lenA,b,lenB,r,lenR);
    rep(i,0,lenR) c[i]-=3*Trans(r[i]);

    // \sum(x,x,x)
    IA3(a,lenA);
    rep(i,0,lenA) c[i]+=2*Trans(a[i]);

    rep(i,0,S-1)
        c[i]/=6;

    rep(i,0,S-1)
        cnt[i]+=c[i];
}
void Print(void) {
    rep(i,0,S-1)
        if (cnt[i]>0)
            printf("%d %lld\n",i,cnt[i]);
}

int main(void) {
    #ifndef ONLINE_JUDGE
    freopen("xsy1728.in","r",stdin);
    freopen("xsy1728.out","w",stdout);
    #endif

    Init();
    Solve1();
    Solve2();
    Solve3();
    Print();

    return 0;
}

【bzoj3771】【xsy1728】Triple的更多相关文章

  1. 【BZOJ3771】Triple(生成函数,多项式运算)

    [BZOJ3771]Triple(生成函数,多项式运算) 题面 有\(n\)个价值\(w\)不同的物品 可以任意选择\(1,2,3\)个组合在一起 输出能够组成的所有价值以及方案数. \(n,w< ...

  2. 【BZOJ3771】Triple 生成函数+FFT

    [BZOJ3771]Triple Description 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: “这把斧头,是不是你的?” 樵夫一看 ...

  3. 新鲜出炉的30个精美的 jQuery & CSS3 效果【附演示和教程】

    新鲜出炉的30个精美的 jQuery & CSS3 效果[附演示和教程]   作为最流行的 JavaScript 开发框架,jQuery 在现在的 Web 开发项目中扮演着重要角色,它简化了 ...

  4. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  5. 【疯狂造轮子-iOS】JSON转Model系列之一

    [疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...

  6. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  7. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  8. 【Win 10 应用开发】应用预启动

    所谓预启动,其实你一看那名字就知道是啥意思了,这是直接译,也找不到比这个叫法更简练的词了.在系统资源允许的情况下(比如电池电量充足,有足够的内存空间),系统会把用户常用的应用程序在后台启动,但不会显示 ...

  9. 【Win 10 应用开发】启动远程设备上的应用

    这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...

随机推荐

  1. centos6.5 ssh安全优化,修改默认端口名,禁止root远程登录

    一.修改默认端口号 第一步: vi /etc/sysconfig/iptables 添加修改后的端口号的配置 -A INPUT -p tcp -m state --state NEW -m tcp - ...

  2. 优化Linux生产服务器的经验之谈

    [51CTO独家特稿]如何优化自己的Linux生产服务器?本文结合实际的工作经验,总结了优化Linux生产服务器的九大要点.如果有些方法您尚未采用,不妨一试. 一.时间同步 生产环境下的服务器对时间的 ...

  3. 向sql server 导入数据库

    在sql server 中选择数据库.右键,还原数据库 选择源设备,点击添加,选中相应的数据库文件. 在目标数据库栏选择相应的数据库名称 点击下一步.

  4. 3d中的坐标系的概念

    世界坐标系 世界坐标系是一个特殊的坐标系,它建立了描述其它坐标系所需要的参考框架.从另一方面说能够用世界坐标描述其它坐标系的位置,而不能用更大的.外部的坐标系来描述世界坐标系. 物体坐标系 物体坐标系 ...

  5. [SAP ABAP开发技术总结]字符串表达式String Expressions

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  6. python介绍(转载)

    Python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言 ...

  7. [ZJOI2006]物流运输

    1003: [ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5999  Solved: 2473[Submit][Stat ...

  8. 在ubuntu上配置apue的运行环境

    http://www.apuebook.com/code3e.html 在上面的网站下载代码包,解压得到源码 sudo apt-get install libbsd-dev 安装这个支持,在解压包的m ...

  9. ubuntu 安装遇到黑屏

    1.安装了ubuntu之后,进入登录页面,然后用输入密码后就黑屏了,按ctrl+alt+f1都没用,也进不去命令界面,查找资料后发现是必须在虚拟机->设置->硬件->显示器,上把加速 ...

  10. Redis脚本插件之————执行Lua脚本示例

    Redis在2.6推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行.使用脚本的好处如下: 1.减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在red ...