【XSY3306】alpha - 线段树+分治NTT
题目来源:noi2019模拟测试赛(一)
题意:


题解:
这场三道神仙概率期望题……orzzzy
这题暴力$O(n^2)$有30分,但貌似比正解更难想……(其实正解挺好想的)
注意到一次操作实际上就是在一段区间里乘上了一个形如$px+(1-p)$的多项式,设把所有多项式合并得到一个多项式$F(x)$,那么我们要求的答案实际上就是:
$$[x^k]F(x)$$
那么可以先离散化坐标,然后开一棵线段树,用vector维护每个点(即最小不可再分的区间)上要乘的多项式,最后dfs一遍线段树,用分治NTT合并每个点自身的多项式,再合并子树的多项式即可。
时间复杂度$O(nlog^3n)$
口胡起来很简单但是写起来很恶心……
代码:
NTT写的挫,人傻自带大常数,跑了4.3s
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
#define mod 998244353
#define G 3
using namespace std;
typedef long long ll;
typedef double db;
struct task{
int l,r,p;
}t[];
struct node{
int l,r;
}tr[];
int n,k,cnt=,tn=,nw[],tmp[],lsh[],ans[][];
vector<int>v[];
namespace Poly{
namespace NTT{
int bit,bitnum,rev[],W[][];
int fastpow(int x,int y){
int ret=;
for(;y;y>>=,x=(ll)x*x%mod){
if(y&)ret=(ll)ret*x%mod;
}
return ret;
}
void pre(){
int rG=fastpow(G,mod-);
for(int i=;i<=;i++){
W[<<i][]=fastpow(G,(mod-)/(<<i));
W[<<i][]=fastpow(rG,(mod-)/(<<i));
}
}
void getr(int l){
for(bit=,bitnum=;bit<l;bit<<=,bitnum++);
for(int i=;i<bit;i++){
rev[i]=(rev[i>>]>>)|((i&)<<(bitnum-));
}
}
void ntt(int *s,int op){
for(int i=;i<bit;i++){
if(i<rev[i])swap(s[i],s[rev[i]]);
}
for(int i=;i<bit;i<<=){
int w=W[i<<][op==-];
for(int p=i<<,j=;j<bit;j+=p){
int wk=;
for(int k=j;k<i+j;k++,wk=(ll)wk*w%mod){
int x=s[k],y=(ll)s[k+i]*wk%mod;
s[k]=(x+y)%mod;
s[k+i]=(x-y+mod)%mod;
}
}
}
if(op==-){
int rb=fastpow(bit,mod-);
for(int i=;i<bit;i++){
s[i]=(ll)s[i]*rb%mod;
}
}
}
}
int A[],B[];
void getmul(int *s,int *a,int *b,int len1,int len2){
for(int i=;i<=len1;i++)A[i]=a[i];
for(int i=;i<=len2;i++)B[i]=b[i];
NTT::getr((len1+len2)*);
for(int i=len1+;i<NTT::bit;i++)A[i]=;
for(int i=len2+;i<NTT::bit;i++)B[i]=;
NTT::ntt(A,);
NTT::ntt(B,);
for(int i=;i<NTT::bit;i++){
s[i]=(ll)A[i]*B[i]%mod;
}
NTT::ntt(s,-);
}
void mul(int l,int r,int nw,int *s){
if(l==r){
s[]=(mod-v[nw][l]+);
s[]=v[nw][l];
return;
}
int mid=(l+r)/;
mul(l,mid,nw,s);
mul(mid+,r,nw,s+mid-l+);
getmul(s,s,s+mid-l+,mid-l+,r-mid);
}
}
void updata(int l,int r,int u,int L,int R,int p){
if(L<=tr[l].l&&tr[r].r<=R){
v[u].push_back(p);
return;
}
int mid=(l+r)/;
if(L<=tr[mid].r)updata(l,mid,u*,L,R,p);
if(tr[mid+].l<=R)updata(mid+,r,u*+,L,R,p);
}
int dfs(int l,int r,int u,int x){
int mid=(l+r)/,L,R,mx;
if(l<r){
L=dfs(l,mid,u*,x);
R=dfs(mid+,r,u*+,x+);
mx=max(L,R);
}
if(v[u].size()){
Poly::mul(,v[u].size()-,u,tmp);
}else tmp[]=;
if(l==r){
nw[]=(tr[l].r-tr[l].l+);
Poly::getmul(ans[x],nw,tmp,,v[u].size());
return v[u].size();
}
for(int i=L+;i<=mx;i++)ans[x][i]=;
for(int i=R+;i<=mx;i++)ans[x+][i]=;
for(int i=;i<=mx;i++){
ans[x][i]=(ans[x][i]+ans[x+][i])%mod;
}
Poly::getmul(ans[x],ans[x],tmp,mx,v[u].size());
return v[u].size()+mx;
}
int main(){
scanf("%d",&n);
Poly::NTT::pre();
for(int i=;i<=n;i++){
scanf("%d%d%d",&t[i].l,&t[i].r,&t[i].p);
lsh[++cnt]=t[i].l;
lsh[++cnt]=t[i].r+;
}
scanf("%d",&k);
lsh[++cnt]=;
lsh[++cnt]=;
sort(lsh+,lsh+cnt+);
cnt=unique(lsh+,lsh+cnt+)-lsh-;
for(int i=;i<=cnt;i++){
tr[++tn].l=lsh[i-];
tr[tn].r=lsh[i]-;
}
for(int i=;i<=n;i++){
updata(,tn,,t[i].l,t[i].r,t[i].p);
}
dfs(,tn,,);
printf("%d",ans[][k]);
return ;
}
【XSY3306】alpha - 线段树+分治NTT的更多相关文章
- loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)
题意 题目链接 Sol 线性基+线段树分治板子题.. 调起来有点自闭.. #include<bits/stdc++.h> #define fi first #define se secon ...
- BZOJ.4184.shallot(线段树分治 线性基)
BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...
- BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)
BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...
- 洛谷.3733.[HAOI2017]八纵八横(线性基 线段树分治 bitset)
LOJ 洛谷 最基本的思路同BZOJ2115 Xor,将图中所有环的异或和插入线性基,求一下线性基中数的异或最大值. 用bitset优化一下,暴力的复杂度是\(O(\frac{qmL^2}{w})\) ...
- bzoj4025二分图(线段树分治 并查集)
/* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...
- BZOJ3237:[AHOI2013]连通图(线段树分治,并查集)
Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connec ...
- 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)
Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ...
- 【Luogu3733】[HAOI2017]八纵八横(线性基,线段树分治)
[Luogu3733][HAOI2017]八纵八横(线性基,线段树分治) 题面 洛谷 题解 看到求异或最大值显然就是线性基了,所以只需要把所有环给找出来丢进线性基里就行了. 然后线性基不资磁撤销?线段 ...
- 2019.02.26 bzoj4311: 向量(线段树分治+凸包)
传送门 题意: 支持插入一个向量,删去某一个现有的向量,查询现有的所有向量与给出的一个向量的点积的最大值. 思路: 考虑线段树分治. 先对于每个向量处理出其有效时间放到线段树上面,然后考虑查询:对于两 ...
随机推荐
- TensorFlow实战学习笔记(14)------VGGNet
一.VGGNet:5段卷积[每段有2~3个卷积层+最大池化层][每段过滤器个数:64-128-256-512-512] 每段的2~3个卷积层串联在一起的作用: 2个3×3的卷积层串联的效果相当于一个5 ...
- SLAB
slab:由于内核会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry,这些对象如果每次构建的时候就向内存要一个页(4kb),而其实只有几个字节,这样就会非常浪费,为了解决这个问题 ...
- Project Euler 11 Largest product in a grid
题意:在这个20×20方阵中,四个在同一方向(从下至上.从上至下.从右至左.从左至右或者对角线)上相邻的数的乘积最大是多少? 思路:暴力去枚举以 ( x , y ) 为中心拓展的四个方向 /***** ...
- [TJOI2018]xor
题目大意: 有一棵树,根节点为1.每个点有点权.有两种操作. 1. 求节点x所在子树中点权与y异或的最大值.2. 求x到y的路径上点权与z异或的最大值. 解题思路: 可持久化字典树. 对于第一种操作, ...
- NFS学习
linux下搭建nfs服务: NFS是network filesystem的缩写,它可以通过网络,让不同的机器.不同的操作系统共享文件. NFS支持的功能比较多,默认端口也是随机的,基于远程调用服务( ...
- 手机上怎么去掉a 标签中的img点击时的阴影?
添加: <style type="text/css"> a { -webkit-tap-highlight-color: transparent; -webkit-to ...
- 【Codeforces 469B】Chat Online
[链接] 我是链接,点我呀:) [题意] [题解] 因为你的朋友的时间是固定的. 你完全可以开一个tag[50]的数组,如果tag[i]=1说明i时刻你的基友在线(扫描基友的时间就能 得到 然后你在判 ...
- mysql在windows下主从同步配置
mysql主从同步: 1.为什么要主从同步? 在Web应用系统中,数据库性能是导致系统性能瓶颈最主要的原因之一.尤其是在大规模系统中,数据库集群已经成为必备的配置之一.集群的好处主要有:查询负载. ...
- 敏捷开发-srcum
SCRUM框架包括3个角色.3个工件.5个活动.5个价值 3个角色 1.产品负责人(Product Owner) 2.Scrum Master 3.Scrum团队 3个工具 1.Product Bac ...
- 0x29 总结与练习
搜索真的菜..困扰了很久,上个星期天没休息好导致整个礼拜没有精神.. 大概完成得七七八八了吧.真是深切的体会到暴力出奇迹的疯狂啊. 3.虫食算 从末位开始枚举判断,通过加数可以推出和的字母代表的数.那 ...