BZOJ4303 : 数列
将每个点看成二维坐标点$(i,a_i)$,那么每次操作的范围都是一个矩形。
于是建立KD-Tree,通过打标记支持操作即可。
时间复杂度$O(m\sqrt{n})$。
#include<cstdio>
#include<algorithm>
const int N=50010,P=536870912;
int n,m,i,root,cmp_d,ans,op,A,B,C,D,E;
struct info{
int a,b;
info(){a=1,b=0;}
info(int _a,int _b){a=_a,b=_b;}
info operator+(info x){return info(1LL*x.a*a%P,(1LL*x.a*b+x.b)%P);}
}tmp;
struct node{
int d[2],l,r,Max[2],Min[2];
int cnt,val,sum;
info tag;
}T[N];
inline bool cmp(const node&a,const node&b){return a.d[cmp_d]<b.d[cmp_d];}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void umax(int&a,int b){if(a<b)a=b;}
inline void umin(int&a,int b){if(a>b)a=b;}
inline void up(int x){
T[x].cnt=1;
if(T[x].l){
T[x].cnt+=T[T[x].l].cnt;
umax(T[x].Max[0],T[T[x].l].Max[0]);
umin(T[x].Min[0],T[T[x].l].Min[0]);
umax(T[x].Max[1],T[T[x].l].Max[1]);
umin(T[x].Min[1],T[T[x].l].Min[1]);
}
if(T[x].r){
T[x].cnt+=T[T[x].r].cnt;
umax(T[x].Max[0],T[T[x].r].Max[0]);
umin(T[x].Min[0],T[T[x].r].Min[0]);
umax(T[x].Max[1],T[T[x].r].Max[1]);
umin(T[x].Min[1],T[T[x].r].Min[1]);
}
}
int build(int l,int r,int D){
int mid=(l+r)>>1;
cmp_d=D,std::nth_element(T+l+1,T+mid+1,T+r+1,cmp);
T[mid].Max[0]=T[mid].Min[0]=T[mid].d[0];
T[mid].Max[1]=T[mid].Min[1]=T[mid].d[1];
if(l!=mid)T[mid].l=build(l,mid-1,!D);
if(r!=mid)T[mid].r=build(mid+1,r,!D);
return up(mid),mid;
}
inline void tag(int x,info p){
T[x].val=(1LL*p.a*T[x].val+p.b)%P;
T[x].sum=(1LL*p.a*T[x].sum+1LL*p.b*T[x].cnt)%P;
T[x].tag=T[x].tag+p;
}
inline void pb(int x){
if(T[x].tag.a==1&&T[x].tag.b==0)return;
if(T[x].l)tag(T[x].l,T[x].tag);
if(T[x].r)tag(T[x].r,T[x].tag);
T[x].tag=info();
}
void change(int x){
if(T[x].Max[E]<A||T[x].Min[E]>B)return;
if(T[x].Min[E]>=A&&T[x].Max[E]<=B){tag(x,tmp);return;}
pb(x);
if(T[x].d[E]>=A&&T[x].d[E]<=B)T[x].val=(1LL*C*T[x].val+D)%P;
if(T[x].l)change(T[x].l);
if(T[x].r)change(T[x].r);
T[x].sum=(T[x].val+T[T[x].l].sum+T[T[x].r].sum)%P;
}
void ask(int x){
if(T[x].Max[E]<A||T[x].Min[E]>B)return;
if(T[x].Min[E]>=A&&T[x].Max[E]<=B){ans=(ans+T[x].sum)%P;return;}
pb(x);
if(T[x].d[E]>=A&&T[x].d[E]<=B)ans=(ans+T[x].val)%P;
if(T[x].l)ask(T[x].l);
if(T[x].r)ask(T[x].r);
T[x].sum=(T[x].val+T[T[x].l].sum+T[T[x].r].sum)%P;
}
int main(){
read(n),read(m);
for(i=1;i<=n;i++)T[i].d[0]=i,read(T[i].d[1]);
root=build(1,n,0);
while(m--){
read(op),read(A),read(B),ans=0,E=op&1;
if(op<2)read(C),read(D),tmp=info(C%=P,D%=P);
if(op==0)change(root);
if(op==1)change(root);
if(op==2)ask(root),printf("%d\n",ans);
if(op==3)ask(root),printf("%d\n",ans);
}
return 0;
}
BZOJ4303 : 数列的更多相关文章
- BZOJ4303:数列
浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...
- C#求斐波那契数列第30项的值(递归和非递归)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- BZOJ1500[NOI2005]维修数列
Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...
- PAT 1049. 数列的片段和(20)
给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列{0.1, 0.2, 0.3, 0.4},我们有(0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1 ...
- 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)
对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...
- fibonacci数列(五种)
自己没动脑子,大部分内容转自:http://www.jb51.net/article/37286.htm 斐波拉契数列,看起来好像谁都会写,不过它写的方式却有好多种,不管用不用的上,先留下来再说. 1 ...
- js中的斐波那契数列法
//斐波那契数列:1,2,3,5,8,13…… //从第3个起的第n个等于前两个之和 //解法1: var n1 = 1,n2 = 2; for(var i=3;i<101;i++){ var ...
- 洛谷 P1182 数列分段Section II Label:贪心
题目描述 对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一数列4 2 4 5 1要分成3段 将其如下分段: [4 ...
- 剑指Offer面试题:8.斐波那契数列
一.题目:斐波那契数列 题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项.斐波那契数列的定义如下: 二.效率很低的解法 很多C/C++/C#/Java语言教科书在讲述递归函数的时 ...
随机推荐
- 怎样从命令行进入mac桌面
www.iwangzheng.com 刚买的mac电脑,想在终端进入桌面,可以用下面的方式 点击桌面右上方的放大镜搜索到Terminal并打开,输入 $ cd /Users 这里会显示多个用户,进入自 ...
- 用chrome模拟微信浏览器访问需要OAuth2.0网页授权的页面
现在很流行微信网页小游戏,用html5制作的小游戏移过来,可以放到微信浏览器中打开,关键是可以做成微信分享朋友圈的形式,大大提高游戏的传播,增强好友的游戏互动. 微信浏览器中打开网页游戏效果还不错,对 ...
- php 二分查找
<?php /**二分查找:查找一个值在数组中的位置 * @$arr:操作的数组,前提是按顺序排列 * @$val:查找的值 * @$start:查找的起始位置,默认从数组的第一个数找起 * @ ...
- datetime中strftime和strptime用法
from datetime import * format = "%Y-%m-%d %H:%M:%S" a=datetime.now() day=a.day b=a.replace ...
- JQuery $(function(){})和$(document).ready(function(){})
document.ready和onload的区别——JavaScript文档加载完成事件页面加载完成有两种事件一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件)二是onload,指 ...
- SQL Server游标的使用
转: http://www.cnblogs.com/moss_tan_jun/archive/2011/11/26/2263988.html 游标是邪恶的! 在关系数据库中,我们对于查询的思考是面向集 ...
- HDU 5724 Chess (状态压缩sg函数博弈) 2016杭电多校联合第一场
题目:传送门. 题意:有n行,每行最多20个棋子,对于一个棋子来说,如果他右面没有棋子,可以移动到他右面:如果有棋子,就跳过这些棋子移动到后面的空格,不能移动的人输. 题解:状态压缩博弈,对于一行2^ ...
- [MACOS] Mac上的抓包工具Charles
转载自: http://blog.csdn.net/jiangwei0910410003/article/details/41620363 今天就来看一下Mac上如何进行抓包,之前有一篇文章介绍了使用 ...
- [Android Memory] App调试内存泄露之Context篇(下)
转载地址:http://www.cnblogs.com/qianxudetianxia/p/3655475.html 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用A ...
- yum_rpm(利用dvd建立本地yum库)
#wget "http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os" 建立起了index.html ...