看节目

Description

?  大概就是给定你一种用两个参数\(X\)和\(Y\)随机一个\(1\sim n\)的排列\(p\)的方式,然后给定一个数组\(a\),现在有两种操作:

?  操作\((1,k)\)表示进行\(k\)次重新排列,一次重新排列指的是令新的\(a\)中第\(p_i\)个位置的值等于原来\(a\)中的第\(i\)个位置的值

?  操作\((2,l,r)\)表示查询\(\sum\limits_{i=l}^r a_i\),答案对\(998244353\)取模

?  数据范围:\(1\leq n,m\leq 10^5,233\leq X,Y<998244353,0\leq a_i<998244353,1\leq k\leq 10^9\)

?  

Solution

?  emmm好像第一次碰到这么神秘的分块题qwq记录一下(流下了做题少的泪水qwq)

?  

??  考虑一下随机出来的置换\(p\)的性质

?  我们考虑将这个置换拆成若干个环(\(i\rightarrow p_i\)),记\(h_n\)表示长度为\(n\)的排列的期望环数,考虑从\(h_{n-1}\)推到\(h_n\),那么第\(n\)个元素有\(\frac{1}{n}\)的概率自环,其余情况并入前面的环中,不会增加环数,于是有\(h_n=h_{n-1}+\frac{1}{n}\),调和级数,渐进\(O(logn)\)

?  我们将询问差分一下,这样就变成了若干个前缀和的询问,形如\((x,k)\),表示的是查询重新排列了\(k\)次之后的前缀\(x\)的和,而拆成环之后重新排列其实就相当于在环上面跳(注意是反着跳)

?  因为环数有保证,所以我们可以考虑对于每个环单独计算贡献:对于一个环\(i\),记\(len_i\)该环的长度,\(val_i\)表示该环中的元素破成链之后的结果(下标从\(0\)开始),\(loc_i(k)\)表示重排\(k\)次之后\(i\)的位置,\(f_{i,k}(x)\)表示环\(i\)重排了\(k\)次之后的前缀和,那么有:
\[
f_{i,k}(x)=\sum\limits_{i=0}^{len-1}val_i[loc_i(k)\%len_i\leq x]
\]
??  这个时候就有一个很神秘的做法了:考虑对\(x\)进行分块,我们把所有的询问\((x,k)\)离线(其实在线好像也可以,只是分块维护的数组多一维。。?),按照询问的\(x\)排序,然后一块一块地处理,对于一个\(St\sim Ed\)的块,处理所有满足\(St\leq x\leq Ed\)的询问

?  这样的话我们就需要维护一个数组\(sum[i][j]\),假设当前已经处理完的最后一个块的结尾为\(ed\),那么\(sum[i][j]\)表示第\(i\)个环重排了\(ed\)次之后前\(j\)位的和(也就是\(sum[i][j]=\sum\limits_{i}f_{i,ed}(j)\)),那么对于一个查询\((x,k)\),我们枚举每一个环,将\(sum[i][k\%len_i]\)加入贡献,然后再暴力枚举一下当前块的开始位置\(st\sim x\)的每个位置,计算重排\(k\)次之后这些位置的值的和再加入贡献中即可

?  那么最后的问题就是怎么计算\(sum[i][j]\),我们每处理完一个块中的询问之后,都要将\(ed\)移动到这个块的结尾并重新计算\(sum\),注意到\(f_{i,k}(x)\)其实是一个卷积形式,所以直接NTT就好了(然而实际上因为\([(i+k)\% len_i\leq x]\in \{0,1\}\),所以直接FFT最后再取模好像也没有什么问题,会快)

??  

?  时间复杂度的话,记块大小为\(T\),那么是\(O(\frac{n}{T}nlogn+Tn)\)的,然后当\(T\)取\(\sqrt{nlogn}\)的时候复杂度为\(O(n\sqrt{nlogn})\)的

?  

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#define pb push_back
#define ll long long
using namespace std;
const int N=1e5+10,MOD=998244353;
struct Q{
    int x,id,op;
    ll k;
    Q(int _x=0,int _id=0,int _op=0,ll _k=0){x=_x; id=_id; op=_op; k=_k;}
    friend bool operator < (Q x,Q y){return x.x<y.x;}
}recq[N*2];
vector<int> cir[N];
int len[N],bl[N],loc[N];
int a[N],ans[N],p[N];
int n,m,X,Y;
int cntq,cntcir;
ll K;
int mul(int x,int y){return 1LL*x*y%MOD;}
int plu(int x,int y){y+=y<0?MOD:0; return (1LL*x+y)-(1LL*x+y>=MOD?MOD:0);}
int ksm(int x,int y){
    int ret=1,base=x;
    for (;y;y>>=1,base=mul(base,base))
        if (y&1) ret=mul(ret,base);
    return ret;
}
namespace NTT{/*{{{*/
    const int TOP=18,N=(1<<TOP)+10,G=3;
    int A[N],B[N],W[TOP+1][N][2];
    int rev[N];
    int n,len,invlen;
    void init(){
        int invg=ksm(G,MOD-2);
        int x,invx;
        for (int step=2,lg=1;step<N;step<<=1,++lg){
            x=ksm(G,(MOD-1)/step);
            invx=ksm(x,MOD-2);
            W[lg][0][0]=W[lg][0][1]=1;
            for (int i=1;i<(step>>1);++i){
                W[lg][i][0]=mul(W[lg][i-1][0],x);
                W[lg][i][1]=mul(W[lg][i-1][1],invx);
            }
        }
    }
    void getlen(int n){
        for (int i=0;i<len;++i) A[i]=B[i]=0;
        int bit=0;
        for (len=1;len<=n;len<<=1,++bit);
        rev[0]=0;
        for (int i=1;i<=len;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
        invlen=ksm(len,MOD-2);
    }
    void ntt(int *a,int op){
        int u,v;
        for (int i=0;i<len;++i) if (rev[i]>i) swap(a[i],a[rev[i]]);
        for (int step=2,lg=1;step<=len;step<<=1,++lg)
            for (int st=0;st<len;st+=step)
                for (int i=0;i<(step>>1);++i){
                    v=mul(a[st+i+(step>>1)],W[lg][i][op==-1]);
                    u=a[st+i];
                    a[st+i]=plu(u,v);
                    a[st+i+(step>>1)]=plu(u,MOD-v);
                }
        if (op==1) return;
        for (int i=0;i<len;++i) a[i]=mul(a[i],invlen);
    }
    void calc(){
        ntt(A,1);
        ntt(B,1);
        for (int i=0;i<len;++i) A[i]=mul(A[i],B[i]);
        ntt(A,-1);
    }
}/*}}}*/
namespace Block{/*{{{*/
    const int LG=30;
    int sum[LG][N];
    int sq,num;
    int st,ed;
    int Id(int x){return (x-1)/sq+1;}
    int St(int x){return (x-1)*sq+1;}
    int Ed(int x){return min(n,x*sq);}
    int query(int x,ll k){
        int ret=0,id=Id(x),pos;
        for (int i=1;i<=cntcir;++i)
            ret=plu(ret,sum[i][k%len[i]]);
        int which;
        for (int i=st;i<=x;++i){
            which=bl[i];
            pos=(loc[i]-k%len[which]+len[which])%len[which];
            ret=plu(ret,a[cir[which][pos]]);
        }
        return ret;
    }
    void solve(){
        int now=1,tmp,x;
        sq=sqrt(n*log(n)/log(2.0));
        num=Id(n);
        for (int id=1;id<=num;++id){
            st=St(id); ed=Ed(id);
            while (now<=cntq&&recq[now].x<=ed){
                if (now==cntq)
                    int debug=1;
                tmp=query(recq[now].x,recq[now].k);
                ans[recq[now].id]=plu(ans[recq[now].id],tmp*recq[now].op);
                ++now;
            }
            if (now>cntq) break;

            for (int i=1;i<=cntcir;++i){
                NTT::getlen(len[i]*2);
                for (int j=0;j<len[i];++j) NTT::A[j+1]=a[cir[i][(len[i]-1)-j]];
                for (int j=0;j<len[i];++j) NTT::B[j]=(cir[i][j]<=ed);
                NTT::calc();
                for (int j=0;j<len[i];++j)
                    sum[i][j]=plu(NTT::A[j],NTT::A[j+len[i]]);
            }
        }
        int debug=1;
    }
}/*}}}*/
int myrand(int l,int r){
    X=1LL*X*Y%MOD;
    return X%(r-l+1)+l;
}
void make_per(int *p,int n){
    for (int i=1;i<=n;++i){
        p[i]=i;
        swap(p[myrand(1,i)],p[i]);
    }
}
void prework(){
    int tmp;
    cntcir=0;
    for (int i=1;i<=n;++i){
        if (bl[i]) continue;
        ++cntcir; tmp=-1;
        while (!bl[i]){
            bl[i]=cntcir; loc[i]=++tmp;
            cir[cntcir].pb(i);
            i=p[i];
        }
        len[cntcir]=cir[cntcir].size();
    }
}
int read(){
    int ret=0; char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while ('0'<=ch&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
#endif
    int op,x,l,r,tmpcnt=0;
    cntq=0;
    NTT::init();
    n=read(); m=read(); X=read(); Y=read();
    make_per(p,n);
    for (int i=1;i<=n;++i) a[i]=read();
    cntq=0; K=0;
    prework();
    for (int i=1;i<=m;++i){
        op=read();
        if (op==1)
            K+=read();
        else{
            l=read(); r=read();
            ++tmpcnt;
            recq[++cntq]=Q(l-1,tmpcnt,-1,K);
            recq[++cntq]=Q(r,tmpcnt,1,K);
        }
    }
    sort(recq+1,recq+1+cntq);
    Block::solve();
    for (int i=1;i<=(cntq+1>>1);++i) printf("%d\n",ans[i]);
}

原文地址:https://www.cnblogs.com/yoyoball/p/10261974.html

时间: 2024-10-10 02:02:45

看节目的相关文章

Day12:看节目对于高考的想法

今天看了一个科教频道的说高考的节目~ 老师问孩子的为什么要高考~ 学生说:为了以后不用辛苦,不用像爸妈一样再大冬天奔波,不辜负爸妈的期望~ 学习!高考!科举制度害了多少读书人?! 现在的高考跟科举有区别么? 真的很想跟那些老师说:你一个人只能教一门课,但是你要让孩子至少学好6门课! 你们有没有想过?为什么网上会有人说:你数学是语文老师教的吧! 这句话不只是玩笑! 你把孩子的数学卷子给语文老师做一下看看! 我保证他的考试成绩不如班里的孩子! 这说明了什么? 再未来你的工作不一定用得上你所学习的那些

使用GNU/Linux播放电视节目

目前,生活中很多事情都可以在电脑前完成,学习.工作.音乐.视频等.如果也可以在电脑上收看有线电视节目的话,那就更好了.为此,我购买了圆刚视频采集卡AverMedia C725B.如下图所示. 官方给出的此卡介绍为(详见这里): C725标清采集卡是一张支持AV端子.S端子以及立体声输入的PCI-E撷取卡,可将PAL.NTSC和SECAM等模拟格式影像数字化,撷取并另存为 无压缩的AVI格式档案.C725标清采集卡随附的软件开发工具包(SDK)提供常用功能,能帮助开发者或系统整合商轻松且有效率地完

央视春晚摇一摇最有可能颠覆哪些行业?

昨 晚,全国人民都在跟随着央视春晚摇动着手机.摇啊摇,有的摇出了红包,有的摇出了卡券.开玩笑的说,国家体育总局花了二十年没有搞起来的全民健身运动,微 信只花了一个晚上就达到目的了.其中22:30央视春晚摇一摇送红包这波,微信总摇一摇次数达72亿次,峰值高达一分钟8.1亿次(22:34),送出红 包1.2亿个,背后是牛逼的技术和强大的商业逻辑. 我 必须要为“春晚摇一摇”点32个赞.其一是升级了红包的概念,将微信红包从用户个人行为转向为企业营销行为,商业化才是最有前途的:其二是解放了摇一摇功 能,

无能的力量 -- 《看见》

卢安克坐在草地上,七八个孩子滚在他怀里,打来打去. 我本能地拉住打人孩子的手:"不要这样." "为什么不要这样?" 我就差点说"阿姨不喜欢这样"了,绷住这句话,我试图劝他们:"他会疼,会难受." "他才不会."他们"嘎嘎"地笑,那个被打的小孩也乐. 卢安克坐在小孩当中,不作声,微笑地看着我无可奈何的样子. 后来我问他:"我会忍不住想制止他们,甚至想要去说他们,这是我的第一个反应

南阳14(会场安排问题)

会场安排问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动.现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排. 输入 第一行是一个整型数m(m<100)表示共有m组测试数据.每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动.随后的n行,每行有

直播体验深度优化方案——连麦互动直播

一.前言 移动直播这把火从2015年一直烧到2016年,毫无疑问直播是当前移动互联网最热门的领域之一,在超大热度的引导下直播领域也吸引了大量的商业资本.在这各大直播应用万花齐放的时刻,也正是直播应用面临的真正风口.站在这个风口上,直播应用只把握好风向标,推出具备高用户粘性的差异化功能,才能在这个不断推陈出新的时代站稳脚跟,获得不可动摇的地位. (移动直播火爆) 当前国内大多数的直播应用,使用的是单主播模式,主播与观众仅仅使用文字.点赞.礼物等方式进行互动.在主播直播时,观众如果能够与其进行实时的

VR给传统电视带来的不是噩耗,而是福音

在前不久的<国民美少女>真人秀节目总决赛中,优酷土豆采用了VR技术对总决赛进行现场直播,让广大网友第一次通过互联网看节目的同时体验到堪比现场的震撼视觉效果.这一举动可谓是开创了综艺VR直播的先河,也再次掀起了整个国内市场的VR技术热潮.事实上,越来越多的视频内容和电视节目都在开始尝试使用VR新玩法.在很多传统电视厂商看来,VR是一个巨大的噩耗,不过刘旷个人却认为,VR对于他们来说是一个巨大的新机遇. 至少,VR设备在短时间内不会全面取代电视 在很多人看来,VR设备是以个人为单位,而电视是以家庭

H5大会之后,未来指向何方?

刚刚参加了2015中国H5开发者大会,略有一点收获,与大家分享一下. 一,H5游戏  游戏是什么?蝴蝶互动的凌海说,游戏行业就是IP的核心.我很认同,假设你手里有一批用户,你让他们在一个群里聊天,时间一长还是会有很有用户流失,但是如果你让他们在一起玩游戏呢?他们的留存率是不是明显好多了? 在日本,移动端H5游戏占整个手游市场的一半.而在国内,尚还没有一款可以大红大紫的H5手游问世,除了去年的神经猫.神经猫的极速蹿红又极速烟消云散留下了两个产物,一个是基于此而一炮蹿红的H5开发引擎"白鹭"

稳、准、狠:京东开放平台的“速度与激情”

最近,<速度与激情7>在国内刮起了一股不小的旋风,据统计,<速度与激情7>上映首日便以4.25亿的成绩傲视群雄,远超去年7月<变形金刚4>创下的2.23亿首日纪录.现如今,任何热点事儿都得冠上"速度与激情"的字眼,这无疑从侧面反映了这部剧的火爆. 当然,"速度与激情"也成为了描述企业发展态势的重要关键词,尤其是对当今互联网而言,这部大剧为巨头之间的PK提供了最佳范本.以电商行业为例,在电商迅猛发展的背景下,诸如京东这样的巨头正在通