【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: 向量(线段树分治+凸包)
传送门 题意: 支持插入一个向量,删去某一个现有的向量,查询现有的所有向量与给出的一个向量的点积的最大值. 思路: 考虑线段树分治. 先对于每个向量处理出其有效时间放到线段树上面,然后考虑查询:对于两 ...
随机推荐
- Nginx部署静态资源(及root与alias区别)
root目录与alias目录的区别Nginx路径location配置中,使用root目录与alias目录的区别 1)alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是 ...
- python的包装和授权
包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均 ...
- XSS Chanllenges 16-19
Stage #16 同样为DOM 型XSS ,document.write() 方法 插入代码 \x3cscript\x3ealert(document.domain)\x3c/script\x3e ...
- 安装oracle服务端之后再安装oracle客户端导致sqlplus命令无法使用??
首先小编自述一下所遇到的问题: 昨天在已经安装 oracle 服务端的 win7 X64 主机上安装 oracle client 之后,发现我的sqlplus命令无法用了??经过百度,都说我服务没有开 ...
- java+selenium+testNG+excel 实现 web 网页的自动化测试
webdriver的关键字从excel读取,这样测试人员只需要在excel中填写相关用例即可 前端微站和后台系统的用例可整合在同一excel中,这样可实现前端与后台的闭循环测试 除了一些基本的校验规则 ...
- SpringMVC的DispatcherServlet加载过程
首先在web.xml中配置容器启动监听器,这样在容器启动后Spring会初始化一个ServletContext,负责加载springmvc的九大组件(调用DispatcherServlet.onRef ...
- 如何用Vim提高开发效率
即可 ●输入m获取到文章目录 推荐↓↓↓ C/C++编程 更多推荐<18个技术类公众微信> 涵盖:程序人生.算法与数据结构.黑客技术与网络安全.大数据技术.前端开发.Java.Python ...
- shell脚本监测文件变化
1. 我使用过的Linux命令之du - 查看文件的磁盘空间占用情况 用途说明 du命令是用来查看磁盘空间占用情况的,在Linux系统维护时常会用到,并且通常与df命令搭配使用.首先使用df看一下各个 ...
- Github博客私人订制(一)
这是博客订制的第一步,简单博客的建立. (这里不做截图说明了,贴图实在是太累,有问题大家QQ私聊我) (一)创建Github账号 URL:https://github.com/ (二)登录Github ...
- iOS实现抽屉效果
抽屉效果 在iOS中非常多应用都用到了抽屉效果,比如腾讯的QQ,百度贴吧- --- 1. 终于效果例如以下图所看到的 --- 2.实现步骤 1.開始启动的时候.新建3个不同颜色的View的 1.设置3 ...