NIT GREAT NITYACKE DESTROYS THE UNIVERSE
线段树
一般线段树维护的东西是什么?设其维护的信息的半群 \((A,+)\),维护标记的半群 \((T,\times)\) 和一种运算 \(*\mapsto A*T\to A\)。
要求 \((b+c)*a=b*a+c*a\)。
一般而言,矩阵是满足这东西的较为一般的东西。
注意:这里不包括 Segment Tree Beats 等基于势能分析的非传统线段树。
现在我们看题:[NOIP2022] 比赛。
扫描线,然后单调栈转化成支持 \(a·b\) 历史和、\(a,b\) 区间覆盖的数据结构。
想在 \(O(1)\) 秒钟构造出标记感觉不大现实,考虑用矩阵乘法维护标记,记 \(a,b,S,len\) 为区间 \(a/b\) 和,历史版本和,区间长度,则区间 \(a\) 加上 \(v\) 就是
\]
区间 \(b\) 加就是:
\]
叠加上版本和就是:
\]
然后线段树维护矩阵即可,时间复杂度 \(O((n+m)k^3\log n),k=5\),由于常数过大,可以获得 \(20pts\) 的高分。
然后我们发现,矩阵有很多地方用不上,可以直接拆开。
贡献是形如 \(len\to a,b\to ab\to S\) 的 DAG,最多有 \(9\) 个状态,然后我们只维护这 \(9\) 个数即可。
然后发现这些位置分别是 \((4,0),(4,1),(4,2),(4,3),(0,2),(0,3),(1,2),(1,3),(2,3)\)。
还有两对位置的值重复。
然后把这一部分重新标号,拿出来手动维护就行了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2.5e5+5;
#define ull unsigned long long
struct qsy{
ull a[8];
qsy(){
memset(a,0,sizeof(a));
}
qsy(int A,int B,int C,int D,int E,int F,int G){
a[1]=A,a[2]=B,a[3]=C,a[4]=D,a[5]=E,a[6]=F,a[7]=G;
}
};
int T,n,m;
qsy xds[maxn<<2],add[maxn<<2];
void print(qsy a,int tp){
int mp[8][8];memset(mp,0,sizeof(mp));
if(tp==0){
mp[1][3]=mp[5][2]=a.a[1];
mp[1][4]=a.a[2];
mp[2][3]=mp[5][1]=a.a[3];
mp[2][4]=a.a[4];
mp[5][3]=a.a[5];
mp[3][4]=a.a[6];
mp[5][4]=a.a[7];
for(int i=1;i<=5;i++)mp[i][i]=1;
cout<<endl;
for(int i=1;i<=5;i++){
for(int j=1;j<=5;j++){
cout<<mp[i][j]<<" ,";
}
cout<<endl;
}
cout<<endl;
}else{
cout<<"[ "<<a.a[1]<<" ,"<<a.a[2]<<" ,"<<a.a[3]<<" ,"<<a.a[4]<<" ,"<<a.a[5]<<" ]"<<endl;
}
}
inline qsy operator *(qsy a,qsy b){
qsy c;
c.a[1]=a.a[1]+b.a[1];
c.a[2]=a.a[2]+b.a[2]+a.a[1]*b.a[6];
c.a[3]=a.a[3]+b.a[3];
c.a[4]=a.a[4]+b.a[4]+a.a[3]*b.a[6];
c.a[5]=a.a[3]*b.a[1]+a.a[1]*b.a[3]+a.a[5]+b.a[5];
c.a[6]=a.a[6]+b.a[6];
c.a[7]=a.a[7]+b.a[7]+a.a[3]*b.a[2]+a.a[1]*b.a[4]+a.a[5]*b.a[6];
// print(a,0);cout<<"*"<<endl;print(b,0);cout<<"="<<endl;print(c,0);
return c;
}
inline qsy operator ^(qsy a,qsy b){
qsy c;
c.a[1]=a.a[1]+b.a[3]*a.a[5];
c.a[2]=a.a[2]+b.a[1]*a.a[5];
c.a[3]=a.a[3]+b.a[1]*a.a[1]+b.a[3]*a.a[2]+b.a[5]*a.a[5];
c.a[4]=a.a[4]+b.a[2]*a.a[1]+b.a[4]*a.a[2]+b.a[6]*a.a[3]+b.a[7]*a.a[5];
c.a[5]=a.a[5];
// print(a,1);cout<<"*"<<endl;print(b,0);cout<<"="<<endl;print(c,1);
return c;
}
inline qsy operator +(qsy a,qsy b){
for(int i=1;i<=5;i++)a.a[i]+=b.a[i];
return a;
}
#define ls (k<<1)
#define rs (k<<1|1)
#define mid ((l+r)>>1)
inline void pushup(int k){
xds[k]=xds[ls]+xds[rs];
}
inline void ADD(int k,qsy a){
xds[k]=(xds[k]^a);
add[k]=add[k]*a;
}
inline bool emp(qsy a){
for(int i=1;i<=7;i++)if(a.a[i]!=0)return 0;
return 1;
}
inline void pushdown(int k){
if(emp(add[k]))return ;
ADD(ls,add[k]);ADD(rs,add[k]);
memset(add[k].a,0,sizeof(add[k].a));
}
inline qsy maker(int tp,int v){
qsy rt;
if(tp==1)rt.a[3]=v;
if(tp==2)rt.a[1]=v;
if(tp==3)rt.a[6]=1;
return rt;
}
void modify(int k,int l,int r,int x,int y,int tp,int v=0){
if(x<=l&&r<=y){
return ADD(k,maker(tp,v));
}
pushdown(k);
if(x<=mid)modify(ls,l,mid,x,y,tp,v);
if(mid<y)modify(rs,mid+1,r,x,y,tp,v);
pushup(k);
}
ull query(int k,int l,int r,int x,int y){
if(x<=l&&r<=y)return xds[k].a[4];
pushdown(k);ull res=0;
if(x<=mid)res+=query(ls,l,mid,x,y);
if(mid<y)res+=query(rs,mid+1,r,x,y);
return res;
}
ull ans[maxn];
vector<pair<int,int> > e[maxn];
int tpa=0,tpb=0,a[maxn],b[maxn];
pair<int,int> sta[maxn],stb[maxn];
void build(int k,int l,int r){
xds[k].a[5]=r-l+1;
if(l==r)return ;
build(ls,l,mid);build(rs,mid+1,r);
}
signed main(){
// freopen("match3.in","r",stdin);
// freopen("match3.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>T>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
cin>>m;
for(int i=1;i<=m;i++){
int l,r;cin>>l>>r;
e[r].push_back({l,i});
}
build(1,1,n);
for(int i=1;i<=n;i++){
modify(1,1,n,i,i,1,a[i]);
// cout<<"a("<<i<<" "<<i<<")+= "<<a[i]<<endl;
while(tpa&&a[i]>a[sta[tpa].second]){
// cout<<"a("<<sta[tpa].first<<" "<<sta[tpa].second<<")+= "<<a[i]-a[sta[tpa].second]<<endl;
modify(1,1,n,sta[tpa].first,sta[tpa].second,1,a[i]-a[sta[tpa].second]),--tpa;
}
tpa++,sta[tpa]={sta[tpa-1].second+1,i};
modify(1,1,n,i,i,2,b[i]);
// cout<<"b("<<i<<" "<<i<<")+= "<<b[i]<<endl;
while(tpb&&b[i]>b[stb[tpb].second]){
// cout<<"b("<<stb[tpb].first<<" "<<stb[tpb].second<<")+= "<<b[i]-b[stb[tpb].second]<<endl;
modify(1,1,n,stb[tpb].first,stb[tpb].second,2,b[i]-b[stb[tpb].second]),--tpb;
}
tpb++,stb[tpb]={stb[tpb-1].second+1,i};
modify(1,1,n,1,n,3);
// cout<<"Genshin"<<endl;
for(auto P:e[i]){
ans[P.second]=query(1,1,n,P.first,i);
}
}
for(int i=1;i<=m;i++)cout<<ans[i]<<"\n";
return 0;
}
联考题
代码待补
NIT GREAT NITYACKE DESTROYS THE UNIVERSE的更多相关文章
- 【SAP Business Objects】Universe中的@prompt语法
@Prompt 函数的语法: @Prompt('message','type',[lov],Mono|Multi,free|constrained|primary_key,persistent|not ...
- Codeforces Round #336 (Div. 2) A. Saitama Destroys Hotel 模拟
A. Saitama Destroys Hotel Saitama accidentally destroyed a hotel again. To repay the hotel company ...
- Codeforces Round #336 (Div. 2)A. Saitama Destroys Hotel 水题
A. Saitama Destroys Hotel 题目连接: http://www.codeforces.com/contest/608/problem/A Description Saitama ...
- [C++]Saving the Universe——Google Code Jam Qualification Round 2008
Google Code Jam 2008 资格赛的第一题:Saving the Universe. 问题描述如下: Problem The urban legend goes that if you ...
- ubuntu enable all Ubuntu software (main universe restricted multiverse) repositories use
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu $(lsb_release -sc) main universe ...
- Universe Design Tool Using JDBC connect Sybase/Oracle Get Error
一.针对Sybase 1 使用SAP Universe 设计工具连接Sybase数据库报错,报错如下: “CS: Java Class not found in classpath : com.syb ...
- 【SerpentAI:Python开源游戏智能体开发框架——相比OpenAI Universe可导入自己的游戏、可脱离Docker/VNC运行】
https://weibo.com/fly51fly?from=myfollow_all&is_all=1#1514439335614 [SerpentAI:Python开源游戏智能体开发框架 ...
- grep init 与 grep [i]nit
看grep的知识点的时候,在XXX博客里看到一个这样的例子,一直在纠结,纠结,init与[i]nit 匹配到的东西不应该时一样的嘛,为什么一个匹配得出来,一个不行.后来在群里问了某位大哥,耐心的讲解, ...
- (17)Questioning the universe
https://www.ted.com/talks/stephen_hawking_asks_big_questions_about_the_universe/transcript00:13There ...
- TED_Topic4:How I fell in love with quasars, blazars and our incredible universe
By Jedidah Isler # Background about our speaker Jedidah Isler studies blazars(耀变天体) — supermassive h ...
随机推荐
- 使用conditional 实现线程精准通讯
实现3个线程之间依次执行 比如有3个线程A,B,C ,需要按照顺序执行,ABC,ABC 依次执行. 这个使用可以使用 Lock 的 conditional来实现线程之间精准通讯. 点击查看代码 pac ...
- .NET 中的中间件(Middleware)
ASP.NET Core 中间件 什么是中间件(Middleware)? 中间件是组装到应用程序管道中以处理请求和响应的软件. 每个组件: 选择是否将请求传递给管道中的下一个组件. 可以在调用管道中的 ...
- 利用Catalina快速重新指定tomcat的代码路径
思路: 在/tomcat/conf/Catalina/localhost目录下,建立对应的xml文件,来定义. 方法: 比如:想在 Http://localhost/test-api 显示,且代码放在 ...
- 打破格式壁垒 !COS助力腾讯文档优化在线预览效果
说起腾讯文档,相信大家对此并不陌生.在新冠疫情防控期间,腾讯文档在人员流动排查.健康信息收集.居家学习.协同办公等场景发挥了巨大的作用. 腾讯文档不仅支持新建word.excel.ppt.思维导图.流 ...
- django内置序列化组件(drf前身)
目录 一.django内置序列化组件(drf前身) 一.django内置序列化组件(drf前身) 一.django内置序列化组件(drf前身) 这里的内置序列化组件,其实就是实现将后端数据,存放到字典 ...
- Qt编写可视化大屏电子看板系统31-模块9视频监控
一.前言 视频监控模块采用ffmpeg作为解码内核,可以在系统设置中填入一个视频地址,同时支持本地视频文件.USB摄像机.远程onvif摄像机(海康大华等).网络视频地址,大屏系统中默认有一个视频监控 ...
- Java子线程无法获取Attributes的解决方法
在Java多线程编程中,开发者经常会遇到子线程无法获取主线程设置的Attributes的问题.Attributes通常用于存储与当前线程相关的数据,尤其在Web应用中,它们常用于请求上下文的管理.然而 ...
- JMeter JDBC 请求实战宝典
<JMeter JDBC 请求实战宝典> 宝子们,今天咱就来唠唠 JMeter 里超厉害的 JDBC 请求,这玩意儿就像是数据库世界的神奇魔杖,能帮咱把数据库里的各种秘密(数据)都挖出来, ...
- 按部就班--从零开始建设k8s监控(二)
前言 书接上文,prometheus已经安装好了,并且能够对k8s的整体状态进行监控,但是我们还需要更多 环境准备 组件 版本 操作系统 Ubuntu 22.04.4 LTS docker 24.0. ...
- 敏捷开发:如何高效开每日站会(Daily Stand-up Meeting)
介绍 在敏捷开发框架 Scrum 中,每日站会(Daily Stand-up Meeting,又叫 Daily Scrum)是 Sprint 迭代开发中,一个很重要的流程,一个重要的例会.在有限的时间 ...