首页 > 其他分享 >我一脚踹他下去。

我一脚踹他下去。

时间:2023-12-04 18:22:39浏览次数:20  
标签:return mat int rep 矩阵 下去 一脚 struct

先致敬 houzhe 学长经典:

我看到我的队友写了个又臭又长的线段树,维护了一堆 tag,于是一脚把他踹下去,写了个线段树维护矩阵,然后就过了。

回到这题,题意即为求一段连续的版本 \([x,y]\) 中,所有版本的区间 \([l,r]\) 的值的平方和。

首先显然可以变成 \([1,y]\) 版本的答案减去 \([1,x]\) 版本的答案。然后变成一个历史版本和问题。解决历史版本和问题自然会想到维护矩阵。当然你打 tag 也是可以的,但是这样的话建议还是从矩阵的角度去推更新,否则很容易出问题。

具体地,SGT 上每个位置维护一个 \(4\times 4\) 的矩阵,记录区间和,区间平方和,区间长度和区间历史版本和四个量,把 \(\sum(a_i+k)^2\) 套路化地拆成 \(\sum a_i^2+\sum a_i\times k+len\times k^2\),这也是一个矩阵很好维护的形式。每做完一次操作之后更新历史和即可。

细节不是很多,需要注意的有:

  • tag 的矩阵初始值是单位矩阵而不是全 \(0\) 矩阵。

  • \(a_i\) 和更新的 \(x\) 都可能是负数。

结束了。跑的还挺快……吗?至少过了而且不是最劣解。/kk

code:

点击查看代码
int n,m,q,a[N],ans[N];
struct node{int l,r,x;}b[N];
struct Node{int l,r,s,id;};
vector<Node> g[N];
il int Mod(int x,int y){return x+y>=mod?x+y-mod:x+y;}
struct SGT{
	struct mat{
		int a[4][4];
		mat(){mems(a,0);}
		il void reset(){mems(a,0);rep(i,0,3)a[i][i]=1;}
		il mat operator*(const mat &rhs)const{
			mat r;
			rep(k,0,3)rep(i,0,3)rep(j,0,3)r.a[i][j]=Mod(r.a[i][j],1ll*a[i][k]*rhs.a[k][j]%mod);
			return r;
		}
		il mat operator+(const mat &rhs)const{
			mat r;
			rep(i,0,3)rep(j,0,3)r.a[i][j]=Mod(a[i][j],rhs.a[i][j]);
			return r;
		}
	};
	struct Tnode{mat x,tag;}tr[N<<2];
	il void pushup(int o){tr[o].x=tr[o<<1].x+tr[o<<1|1].x;}
	il void reset(int o,mat &k){tr[o].x=tr[o].x*k,tr[o].tag=tr[o].tag*k;}
	il void pushdown(int o){reset(o<<1,tr[o].tag),reset(o<<1|1,tr[o].tag),tr[o].tag.reset();}
	void build(int l,int r,int o){
		tr[o].tag.reset();
		if(l==r)return tr[o].x.a[0][0]=Mod(a[l],mod),tr[o].x.a[0][1]=1ll*a[l]*a[l]%mod,tr[o].x.a[0][2]=1,void();
		int mid=(l+r)>>1;
		build(l,mid,o<<1),build(mid+1,r,o<<1|1);
		pushup(o);
	}
	void update(int l,int r,int o,int x,int y,mat k){
		if(l>=x&&r<=y)return reset(o,k);
		pushdown(o);
		int mid=(l+r)>>1;
		if(x<=mid)update(l,mid,o<<1,x,y,k);
		if(y>mid)update(mid+1,r,o<<1|1,x,y,k);
		pushup(o);
	}
	int query(int l,int r,int o,int x,int y){
		if(r<x||l>y)return 0;
		if(l>=x&&r<=y)return tr[o].x.a[0][3];
		pushdown(o);
		int mid=(l+r)>>1;
		return Mod(query(l,mid,o<<1,x,y),query(mid+1,r,o<<1|1,x,y));
	}
}T;
void Yorushika(){
	scanf("%d%d%d",&n,&m,&q),m++;
	rep(i,1,n)scanf("%d",&a[i]);
	rep(i,2,m)scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].x);
	rep(i,1,q){
		int l,r,x,y;scanf("%d%d%d%d",&l,&r,&x,&y);
		g[x].eb((Node){l,r,-1,i}),g[y+1].eb((Node){l,r,1,i});
	}
	T.build(1,n,1),b[1]={1,1,0};
	SGT::mat x;x.reset();
	rep(i,1,m){
		SGT::mat tmp;int x=b[i].x;
		tmp.a[0][0]=1,tmp.a[0][1]=Mod(2ll*x%mod,mod);
		tmp.a[1][1]=1;
		tmp.a[2][0]=Mod(x,mod),tmp.a[2][1]=1ll*x*x%mod,tmp.a[2][2]=1;
		tmp.a[3][3]=1;
		T.update(1,n,1,b[i].l,b[i].r,tmp);
		tmp.reset(),tmp.a[1][3]=1;
		T.reset(1,tmp);
		for(Node j:g[i])ans[j.id]=Mod(ans[j.id],Mod(mod,T.query(1,n,1,j.l,j.r)*j.s));
	}
	rep(i,1,q)printf("%d\n",ans[i]);
}
signed main(){
	int t=1;
	//	scanf("%d",&t);
	while(t--)
		Yorushika();
}

标签:return,mat,int,rep,矩阵,下去,一脚,struct
From: https://www.cnblogs.com/yinhee/p/paimonSGT.html

相关文章

  • 把故事继续写下去
    在这个快速社交的时代,我等一段回复等了3个月。更像是一段有趣的故事从我16岁,续写到了现在。事情起因是我有一天回忆起中学的时光,于是给两三个曾经的高中好友在百年沉寂的QQ上了留了言,大概的意思就是:“你们最近怎么样?还回过母校吗?”我一向遵循的是【君子之交淡如水】的原则,所以......
  • 真正的鲜花——genshin着走下去
    吃饭遇到了CQ。坐下后,CQ问我:“你的原神之旅还有多久啊”我愣了一下,似懂非懂地回答道“下周六”“对于以后的原神旅途怎么安排呢?”这下听懂了。就像发现眼前有坨屎一旁有摄像头于是顿悟为巧克力蛋糕然后猛吃的恍然大悟。我也是谜语人了“我玩了四年半的原神了,下周抽卡。”“......
  • AITO问界崛起的“临门一脚”,落在了赛力斯汽车的智慧工厂里
    文|智能相对论作者|沈浪AITO问界新M7的销量爆了,口碑也紧接着“爆”了。AITO问界新M7系列上市以来50天,累计大定突破8万辆。AITO问界M9预计今年12月上市,预订超过了1.5万辆。根据最新公布的产销数据,在过去的10月份,AITO问界系列交付新车1.27万辆,单车型单月交付直接破万,创历史新高。......
  • Android就业市场究竟怎么样,还能不能坚持下去
    本人毕业于普通本科,计算机专业,从事Android开发已有5年。2021年受疫情影响,互联网行业整体低迷,我所在公司也进行了裁员,但是我也没有被优化。没想到疫情开发后,没等到春风,却成了失业人员之一,真是人生难以预料啊。就这样,我离开了工作了3年多的公司。开启了2023年的面试旅程。如今,选择从......
  • uni 组件自带方法怎么传自定义参数下去
    html<pickermode="selector"class="pickers"@change="PickerLittleChange($event,operatingState)" :value="indexs"range-key="dictLabel":range="operatingState"> <viewclas......
  • Qt Debug 不下去的一个解决方法
    今天遇到一个难题。在debug时,使用qt函数载入自写的dll时,载入时,崩溃。如果不用F5可以顺利运行删除临时文件文件夹等方式都试过,问题依然存在。当我删除所有的断点后,重新编译,然后设置断点,跟踪运行正常。问题原因没有找到。错误关键词:ZwMapViewOfSection ......
  • 版本升级 | v1.0.13发布,传下去:更好用了
    新发行版来啦~本次更新主要聚焦兼容性的提升及结果报告格式的增加,另外对部分解析逻辑及使用体验进行了优化。在这里特别鸣谢大佬@Hugo-X在社区仓库提交的PR~后续,OpenSCA项目组会继续致力于完善本地能力闭环,覆盖更多场景。 v1.0.13更新内容本地漏洞库兼容多数据格式支......
  • 版本升级 | v1.0.13发布,传下去:更好用了
    新发行版来啦~本次更新主要聚焦兼容性的提升及结果报告格式的增加,另外对部分解析逻辑及使用体验进行了优化。在这里特别鸣谢大佬@Hugo-X在社区仓库提交的PR~后续,OpenSCA项目组会继续致力于完善本地能力闭环,覆盖更多场景。v1.0.13更新内容本地漏洞库兼容多数据格式支持SQLite、CSV格......
  • stm32芯片焊接区分第一脚
    辨认引脚:芯片的第一脚,正放芯片,面对型号字符,然后,在芯片的左下方为第一脚。也可以把芯片的缺口朝左放置,左下角也就是第一脚了。许多厂家会在第一脚旁边打上一个小圆点作为标记。知道了第一脚之后,按照反时针方向去走,依次是第2至第40引脚。(1脚与40脚遥遥相对)。 两个圆点......
  • 2023-07-02:给定一个1~N的排列,每次将相邻两数相加,可以得到新的序列,长度是N-1 再对新的
    2023-07-02:给定一个1~N的排列,每次将相邻两数相加,可以得到新的序列,长度是N-1再对新的序列,每次将相邻两数相加,可以得到新的序列,长度是N-2这样下去可以最终只剩一个数字比如:31244367916现在如果知道N,和最后的数字sum,反推最原始的序列是什么如果有多个答案,返回字典序......