【bzoj3771】【xsy1728】Triple
【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的更多相关文章
- 【BZOJ3771】Triple(生成函数,多项式运算)
[BZOJ3771]Triple(生成函数,多项式运算) 题面 有\(n\)个价值\(w\)不同的物品 可以任意选择\(1,2,3\)个组合在一起 输出能够组成的所有价值以及方案数. \(n,w< ...
- 【BZOJ3771】Triple 生成函数+FFT
[BZOJ3771]Triple Description 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: “这把斧头,是不是你的?” 樵夫一看 ...
- 新鲜出炉的30个精美的 jQuery & CSS3 效果【附演示和教程】
新鲜出炉的30个精美的 jQuery & CSS3 效果[附演示和教程] 作为最流行的 JavaScript 开发框架,jQuery 在现在的 Web 开发项目中扮演着重要角色,它简化了 ...
- 【疯狂造轮子-iOS】JSON转Model系列之二
[疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付
前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(上)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- 【Win 10 应用开发】应用预启动
所谓预启动,其实你一看那名字就知道是啥意思了,这是直接译,也找不到比这个叫法更简练的词了.在系统资源允许的情况下(比如电池电量充足,有足够的内存空间),系统会把用户常用的应用程序在后台启动,但不会显示 ...
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
随机推荐
- web错误
“/Web”应用程序中的服务器错误. 服务器 'LD-PC' 上的 MSDTC 不可用. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误 ...
- 【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)
斐波那契数列:0.1.1.2.3.5.8.13………… 他的规律是,第一项是0,第二项是1,第三项开始(含第三项)等于前两项之和. > 递归实现 看到这个规则,第一个想起当然是递归算法去实现了, ...
- 【转载】ODBC, OLEDB, ADO, ADO.Net的演化简史
原文:ODBC, OLEDB, ADO, ADO.Net的演化简史 1.演变历史 它们是按照这个时间先后的顺序逐步出现的,史前->ODBC->OLEDB->ADO->ADO.N ...
- Create,Insert
创建表 create table people ( id int ,name ) ) create table toys ( id int ,name ) ,people_id int ) CREAT ...
- How To Tune or Test PLSQL Code Performance in Oracle D2k Forms
You can test or tune your program unit performance in Oracle forms with Ora_Prof package.Suppose you ...
- SqlServer 存储过程分页
适用于2005以上版本 create procedure [dbo].[SP_GetPageList] ( @columns nvarchar(max), --查询字段 @tablename nvar ...
- EditPlus添加到右键菜单
1.Alt+R 键打开“运行” 2.“运行”中输入:regedit 打开注册表 (1.在 "我的电脑HKEY_CLASSES_ROOT*" 下新建项 shell: (2.在 ...
- HNOI2006-公路修建问题(二分答案+并查集)
公路修建问题 OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织成立了,旨 ...
- JMS【二】--ActiveMQ简单介绍以及安装
现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的. 上篇博文JMS[一]--JMS基本概念,我们介绍了消息通信的规范JMS,我 ...
- elcipse 安装svn插件 转载
1.下载最新的Eclipse,我的版本是3.7.2 indigo(Eclipse IDE for Java EE Developers)版 如果没有安装的请到这里下载安装:http://ecli ...