ABC 368 G - Add and Multiply Queries

2024-08-26 18:44
文章标签 abc 368 add multiply queries

本文主要是介绍ABC 368 G - Add and Multiply Queries,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原题链接:G - Add and Multiply Queries

题意:给出数组a和b,三种操作,第一种:以 1 i x 的形式给出。用x替换ai​。第二种:以 2 i x 的形式给出。用x代替 bi​ 。第三种:以3 l r的形式给出,初始值为0,从l到r每个位置上可以选择加上a[i],或者乘上b[i],输出最大值。

思路:链表+set+树状数组+二分。题目中给出了答案的范围不会超过1e18,那么就可以知道每次第三种操作的区间里面b数组大于等于2的数的数量不会大于63个。

因为初始值是0,所以第一次操纵一定是选择a[l],从l+1开始到b数组里面第一次出现大于等于2的数之间,肯定是之间加上a数组里面的数更加优秀,那么这一段区间的和怎么维护呢?因为操作一会修改a数组,所以需要可以满足区间查询,单点修改的数据结构,那么就是树状数组。这样操作一就完成。

考虑如何快速的找到b数组里面大于等于2的数的位置?可以使用链表来维护,链表的含义是当前位置的b数组值大于等于2的下一个大于等于2的位置,这样的话,就可以先找到[l,r]区间里面第一个大于等于2的位置,然后不断的往后面跳跃,直到大于r。那么怎么快速的找到第一个位置呢?可以想打把每一个节点的位置塞到set里面,然后二分的查找就可以了。这样操作三就完成了。

对于操作二来说,因为是用链表来写的,所以如果改变的值大于等于2,那么就把改变的位置加入链表,如果小于2,并且b数组这个位置大于2,那么就把这个节点舍弃。如何快速的找当前点之前的呢,还是在set里面二分。

//冷静,冷静,冷静
//调不出来就重构
//#pragma GCC optimize(2)
//#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=1000000007;
ll a[N],b[N],r[N],tree[N],l[N]; 
ll lowbit(ll x)
{return x&(-x);
}
ll query(ll x)
{ll sum=0;while(x){sum+=tree[x];x-=lowbit(x);}return sum;
}
void updata(ll x,ll n,ll vel)
{while(x<=n){tree[x]+=vel;x+=lowbit(x);}
}
void Jiuyuan()
{ll n;cin>>n;for(int i=1;i<=n;i++)//读入a,并且更新树状数组 {cin>>a[i];updata(i,n,a[i]);}for(int i=1;i<=n;i++)cin>>b[i];ll id=n+1;set<ll> op;for(int i=n;i;i--)//建立双向链表 {if(b[i]>=2){r[i]=id;l[id]=i;op.insert(id);id=i;}}r[0]=id;l[id]=0;op.insert(id);ll q;cin>>q;while(q--){ll nm;cin>>nm;if(nm==1){ll wz,x;cin>>wz>>x;updata(wz,n,-a[wz]+x);a[wz]=x;}else if(nm==2){ll wz,x;cin>>wz>>x;ll hj=*op.lower_bound(wz);//先找到大于等于x的位置,然后这个位置之前的一个,那么wz就会被夹在中间 hj=l[hj];if(x>=2){ll a=hj,b=wz,c=r[hj];if(c==wz)c=r[c];//如果本身就是大于等于2,那么就需要在多跳一次 r[a]=b;l[b]=a;r[b]=c;l[c]=b;op.insert(wz);}else{if(b[wz]>=2){ll a=hj,b=wz,c=r[hj];if(c==wz)c=r[c];r[a]=c;l[c]=a;op.erase(wz);}}b[wz]=x;}else{ll x,y;cin>>x>>y;ll cs=a[x];x++;ll hj=*op.lower_bound(x);//找到第一个大于等于x并且满足要求的位置 while(hj<=y){ll xx=x,yy=hj-1;if(yy>=xx)//如果中间有b数组为1的区间,那么就加上a数组的值 {cs+=query(yy);cs-=query(xx-1);}cs=max(cs+a[hj],cs*b[hj]);//1*6 1+6 明显后者更好,所以比较一下 x=hj+1;hj=r[hj];}cs+=query(y);//如果有多余的,那么就加上a数组的值 cs-=query(x-1);cout<<cs<<endl;}}
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);ll T=1;
//	cin>>T;while(T--){Jiuyuan();}return 0;
} 

这篇关于ABC 368 G - Add and Multiply Queries的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1109379

相关文章

Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.B

一个bug日志 FATAL EXCEPTION: main03-25 14:24:07.724: E/AndroidRuntime(4135): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.syyx.jingubang.ky/com.anguotech.android.activity.Init

ubuntu16.04 Git add 使用tab键卡死

以前使用Ubuntu14.04 进行git add 操作时使用TAB键可以很快自动补全,但自从使用16.04使用TAB半天没有反应。 一开始以为是Git版本问题,后验证与Git无关。 搜索发现与Dash有关,以下是博客原文: http://www.51testing.com/html/50/n-1245050.html 今天碰到一个问题git 后面的参数用Tab键无法补全

Add All -uva优先队列的应用

题目的解法属于贪心,因为cost=a1+a2,所以要保证每次的cost最小,所以说,每次将队列中最小的两个相加,得出来的数放入队列中,再取2个最小的相加,直到全部加完,所以这就涉及了一个取2个最小数的问题,我说一下我一开始的做法 #include<stdio.h>#include<iostream>#include<stdlib.h>using namespace std;#define

Android studio jar包多层嵌套,Add library '__local_aars__:...@jar' to classpath问题

在添加jar包,早app下的build.gradle中的 implementation files('libs/jar包的名字.jar') 修改为 api files('libs/jar包的名字.jar') implementation 单层引用,只引用当前jar包层, api 多层引用,应用当前jar包层,已经jar包引用的jar包层

unable to access android sdk add-on list解决办法

mac环境,由于不小心删掉了sdk文件夹的内容,拷贝别人的文件内容过来后,发现sdkmanager不见了。 慌乱中重装了Android Studio。 打开app后发现如下提示:unable to access android sdk add-on list 解决办法: 在 Android Studio 安装目录 bin/idea.properties 文件最后追加一句 disabl

GIT:git add命令指定文件夹

git add命令可以指定文件夹来添加文件到git仓库中。 1、使用相对路径         当你在命令行中使用git add命令时,可以通过相对路径指定文件夹。例如,如果你的文件夹名为myfolder,可以使用以下命令将整个文件夹添加到git仓库中: git add myfolder/ 注意,路径名后面的斜杠是必需的,它表示将文件夹中的所有文件都添加。如果不加斜杠,命令会视为添加具

js中怎样对“abc”进行MD5、sha256哈希计算?

在 JavaScript 中,可以使用 CryptoJS 库来进行 MD5 哈希计算。首先,你需要在 HTML 文件中导入 CryptoJS 库,例如: <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script> 然后,在 JavaScript 文件中,可

2024国赛数学建模ABC题思路模型

完整的思路模型请查看文末名片 完整的思路模型请查看文末名片 完整的思路模型请查看文末名片

【CodeForces】266E More Queries to Array... 线段树

E. More Queries to Array... time limit per test 5 seconds memory limit per test 256 megabytes input standard input output standard output You've got an array, consisting of n

【ZOJ】3881 From the ABC conjecture【暴力容斥】

传送门:【ZOJ】3881 From the ABC conjecture 复杂度大概 O(N0.67) O(N^{0.67}),我也不会算www,首先转换一下(我们是根据积性函数打表找规律得到的,也可以推出来)使得: g(N)=∏pi ϵ N(pia+1) g(N)=\prod_{pi~\epsilon ~N} (pi^a+1) 暴力展开发现贡献为: h(N)=