Codeforces

思路

定义\(f_{l,r}(x)\)表示数\(x\)从\(l\)进去\(r\)出来的时候会变成什么样子。容易发现这个函数是个分段函数,每一段都是斜率为1的一次函数,并且段数就是区间长度。(可能有什么+1-1的)

如果我们能在线段树维护出这个东西,那么查询的时候在线段树上拉出一些函数,依次代进去,就可以了。

两个函数怎么复合呢?做一个two pointers,可以证明这样复杂度是线性的。

咋证明?懒得说了,去别的神仙的博客看吧。

代码

实现的时候似乎不能把\(l,r\)都存下来,否则询问会特别慢。

为什么呢?我也不知道……

#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 1110002
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char __sr[1<<21],__z[20];int __C=-1,__zz=0;
inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
inline void print(register int x)
{
if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
while(__z[++__zz]=x%10+48,x/=10);
while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
}
void file()
{
#ifdef NTFOrz
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n;ll P;
ll a[sz]; struct hh{ll l,b;}; // x \in [l,r], y=x+b typedef vector<hh> func;
func tr[sz<<1];
#define ls k<<1
#define rs k<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
ll calc(const func &V,ll x)
{
int l=0,r=(int)V.size()-1,pos=0;
while (l<=r)
{
int mid=(l+r)>>1;
if (x>=V[mid].l) pos=mid,l=mid+1;
else r=mid-1;
}
return x+V[pos].b;
}
func merge(func A,const func &B)
{
int p=0;
func ret;
int aa=A.size(),bb=B.size();
#define add(L,BB) ((ret.empty()||ret.back().b!=BB)?ret.push_back((hh){L,BB}),0:0)
for (int i=0;i<=(int)A.size()-1;)
{
ll yl=A[i].l+A[i].b,yr;
if (A[i].l==-1e17) yl=-1e17;
if (i==aa-1) yr=1e17; else yr=A[i+1].l-1+A[i].b;
while (p&&B[p].l>yl) --p;
while (p<bb-1&&B[p+1].l-1<yl) ++p;
ll r;
if (p==bb-1) r=1e17; else r=B[p+1].l-1;
if (r<yr) add(A[i].l,A[i].b+B[p].b),A[i].l=r-A[i].b+1;
else add(A[i].l,A[i].b+B[p].b),++i;
}
return ret;
#undef add
}
void build(int k,int l,int r)
{
if (l==r) { tr[k].push_back((hh){-(ll)1e17,a[l]}),tr[k].push_back((hh){P-a[l],a[l]-P}); return; }
int mid=(l+r)>>1;
build(lson),build(rson);
tr[k]=merge(tr[ls],tr[rs]);
}
ll query(int k,int l,int r,int x,int y,ll w)
{
if (x<=l&&r<=y) return calc(tr[k],w);
int mid=(l+r)>>1;
if (x<=mid) w=query(lson,x,y,w);
if (y>mid) w=query(rson,x,y,w);
return w;
} int main()
{
file();
int Q;
read(n,Q,P);
rep(i,1,n) read(a[i]);
build(1,1,n);
int l,r;
while (Q--) read(l,r),printf("%I64d\n",(long long)query(1,1,n,l,r,0));
return 0;
}

Codeforces 1172F Nauuo and Bug [线段树]的更多相关文章

  1. 【杂题】[CodeForces 1172F] Nauuo and Bug【数据结构】【线段树】

    Description 给出一个长度为n的序列a和一个整数p 有m组询问,每组询问给出一个区间\([l,r]\) 你需要给出下面这个过程的结果 ans = 0 for i from l to r { ...

  2. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  3. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  4. Codeforces 588E. A Simple Task (线段树+计数排序思想)

    题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...

  5. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  6. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  7. Codeforces 444C DZY Loves Colors(线段树)

    题目大意:Codeforces 444C DZY Loves Colors 题目大意:两种操作,1是改动区间上l到r上面德值为x,2是询问l到r区间总的改动值. 解题思路:线段树模板题. #inclu ...

  8. Codeforces 85D Sum of Medians(线段树)

    题目链接:Codeforces 85D - Sum of Medians 题目大意:N个操作,add x:向集合中加入x:del x:删除集合中的x:sum:将集合排序后,将集合中全部下标i % 5 ...

  9. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

随机推荐

  1. axios ios 微信浏览器session问题

    在ios系统下,微信浏览器使用axios 可能存在seesion不存在的问题,其原因是因为存在跨域 解决方案如下 1.修改域名为同一域名 2.后台允许跨域

  2. 记录用到的mssql的几个方法

    1.RIGHT ( character_expression , integer_expression ) 返回字符串中从右边开始指定个数的字符 character_expression 字符或二进制 ...

  3. java之struts2之ajax

    1.Ajax 技术在现有开发中使用非常多,大多是做管理类型系统.在servlet中可以使用ajax.在struts2中共还可以使用servlet的方式来实现ajax. 2.案例:用户名检查 publi ...

  4. jquery easyui datagrid的一些用法

    获取选中的多选数据 var rows = $('#Id').datagri('getSelections'); 选中单行的数据 var row = $(#Id).datagrid('getSelect ...

  5. Part_four:redis主从复制

    redis主从复制 1.redis主从同步 Redis集群中的数据库复制是通过主从同步来实现的 主节点(Master)把数据分发从节点(slave) 主从同步的好处在于高可用,Redis节点有冗余设计 ...

  6. windows下git创建本地分支并建立对应远程分支

    在对应项目目录下打开命令提示符 git branch -a      查看所有本地和远程分支 git checkout -b [newBranch]     建立本地分支newBranch git p ...

  7. SpringBoot+SpringCloud+vue+Element开发项目——数据库设计

    1.用户表(sys_user) CREATE TABLE `sys_user` ( `id` ) NOT NULL AUTO_INCREMENT COMMENT '编号', `name` ) NOT ...

  8. SpringBoot+SpringCloud+vue+Element开发项目——集成Swagger文档

    在pom.xml文件中添加Maven依赖 <!--swagger--> <dependency> <groupId>io.springfox</groupId ...

  9. HDFS-SecondaryNameNode(SNN)角色介绍

    它出现在Hadoop1.x版本中,又称辅助NameNode,在Hadoop2.x以后的版本中此角色消失.如果充当datanode节点的一台机器宕机或者损害,其数据不会丢失,因为备份数据还存在于其他的d ...

  10. 七年开发经验教你如何正确、安全地停止 SpringBoot 应用

    引言 Spring Boot,作为Spring框架对“约定优先于配置(Convention Over Configuration)”理念的最佳实践的产物,它能帮助我们很快捷的创建出独立运行.产品级别的 ...