题目描述

给你 n 个盒子,有 q 个操作,操作有两种:

  • 第一种操作输入格式为"1 L R A B",表示将编号为L到R的盒子里的石头数量变为(X−L+1)×A mod B,其中 X为盒子的编号。

  • 第二种操作输入格式为"2 L R",表示查询编号为L到R的盒子里的石头总数。

输入输出格式

输入格式:

第一行有两个数字n(1≤N≤109),q(1≤Q≤50000)。

接下来 q行表示询问操作。

输出格式:

对于每个第二种操作,输出石头总数。

输入输出样例

输入样例#1:

6 3
2 1 6
1 1 5 1 2
2 1 6
输出样例#1:

0
3
输入样例#2:

4 5
1 1 4 3 4
2 1 1
2 2 2
2 3 3
2 4 4
2 5 5
输出样例#2:

3
2
1
0
输入样例#3:

4 4
1 1 4 7 9
2 1 4
1 1 4 1 1
2 1 4
输出样例#3:

16
0

说明

Solution:

  本题黑的不行啊,两天就荒(废)在这题上了!

  思路:数学大套路+线段树。

  题目中唯一出现的数学式子:$\sum_\limits{i=1}^{i\leq n} {(i*A\mod B)}$,那么切入点当然是如何快速求该式子咯。

  我们对式子变形:原式$=A*\sum_\limits{i=1}^{i\leq n}{i}-B*\sum_\limits{i=1}^{i\leq n}{\lfloor \frac{i*A}{B} \rfloor}$。

  被减数式子很好算直接忽略,减数式子的解决关键是式子$\sum_\limits{i=1}^{i\leq n}{\lfloor \frac{i*A}{B} \rfloor}$,对此式子我们分情况讨论($A==B$的情况该式子直接算,所以忽略咯):

    1、$A>B$,我们假设$A=kB+r$,则原式子化为$\sum_\limits{i=1}^{i\leq n}{\lfloor \frac{i*(kB+r)}{B} \rfloor}=k*\sum_\limits{i=1}^{i\leq n}{i}+\sum_\limits{i=1}^{i\leq n}{\lfloor \frac{i*r}{B} \rfloor}$,我们把$r$当作新的$A$,那么就将该式子转化为了$A<B$的情况,于是关键就成了$A<B$时如何快速求原式子。

    2、$A<B$,我们将其抽象到平面直角坐标系上,不难发现$\sum_\limits{i=1}^{i\leq n}{\lfloor \frac{i*A}{B} \rfloor}$实际求的是坐标为$(0,0),(n,0),(n,\frac{n*A}{B})$三点围成的三角形的不在$X$轴上的格点个数,可能有点难以理解,我们画图理解(留图待画、手绘勿喷):

如图,对角线上每个被标记的点到x轴的垂线段上的格点(除开x轴的格点),所对应的就是每个$\lfloor \frac{i*A}{B} \rfloor$。我们若直接算下三角的格点个数会很麻烦,但是很容易算出整个矩形的格点个数,我们设$m=\lfloor \frac{n*A}{B} \rfloor$,则矩形的格点个数为$n*m$,我们用矩形的格点个数-上三角的格点个数+对角线上的格点个数,就能得到原式子的值。如何求上三角的格点个数和对角线的格点个数呢?我们把上三角逆时针旋转90度,就能得到一个类似于下三角的一条边为整数的三角形,用同样的方法去求,发现上三角的格点个数恰好等于$\sum_\limits{i=1}^{i\leq m}{\lfloor \frac{i*B}{A} \rfloor}$,因为$A<B$,我们又回到了第1种$A>B$情况,于是可以递归去求(递归边界就是$A|B$返回0)。而对角线斜率为$\frac{\frac{A}{gcd(A,B)}}{\frac{B}{gcd(A,B)}}$,那么横坐标每隔$\frac{B}{gcd(A,B)}$个单位会有一个格点出现,所以对角线上共有$\frac{n*gcd(A,B)}{B}$个格点。不难发现整个递归过程就是个类欧几里得的求法,时间复杂度为$O(\log n)$

  有了上面的结论,我们就能在$O(\log n)$的复杂度下修改一段区间,那么对于原题的区间查询,我们使用懒惰标记,记录每段被修改的$A,B$和前一个点位置$st$,然后任意一度区间$[l,r]$的和都可以用$sum[r]-sum[l-1]$去算,而每个$sum[i]$直接调用上面的递归过程就好了。

  细节太多,注意:区间肯定得离散,而求区间和时用到了前缀和的思想,一个简单的离散方法是对询问的$l,r$,将$l-1,r$离散,然后线段树建树时每个节点维护的是一整段区间,要把每段小的区间都表示出来(开始30分的原因)。

  最后总时间复杂度$O(q\log^2 n)$,稳妥!(>.^_^.<咕咕)

  

代码:

/*Code by 520 -- 9.7*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);++(i))
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);--(i))
#define lson l,m,rt<<1
#define rson m,r,rt<<1|1
using namespace std;
const int N=;
int n,m,flag[N],L[N],R[N],*Q[N],cnt,tot,val[N];
ll A[N],B[N];
struct node{
ll sum,a,b,st,len;
}t[N]; int gi(){
int a=;char x=getchar();
while(x<''||x>'')x=getchar();
while(x>=''&&x<='')a=(a<<)+(a<<)+(x^),x=getchar();
return a;
} il bool cmp(int *a,int *b){return *a<*b;} ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll calc(ll a,ll b,ll n){
ll x=a/b;a%=b;
ll sum=n*(n+)/*x;
if(!a||!b) return sum;
ll lala=n/b,m=a*n/b;
return sum+n*m-calc(b,a,m)+lala;
} il ll solve(ll a,ll b,ll n){
if(n<)return ;
ll g=gcd(a,b);
return n*(n+)/*a-b*calc(a/g,b/g,n);
} il void pushup(int rt){t[rt].sum=t[rt<<].sum+t[rt<<|].sum;} il void gai(ll A,ll B,ll st,int rt){
t[rt].a=A,t[rt].b=B,t[rt].st=st;
t[rt].sum=solve(A,B,st+t[rt].len-)-solve(A,B,st-);
} il void pushdown(int rt){
if(t[rt].b){
gai(t[rt].a,t[rt].b,t[rt].st,rt<<);
gai(t[rt].a,t[rt].b,t[rt].st+t[rt<<].len,rt<<|);
t[rt].b=;
}
} void build(int l,int r,int rt){
if(l+==r){t[rt]=node{,,,,val[r]-val[l]};return;}
int m=l+r>>;
t[rt]=node{,,,,val[r]-val[l]};
build(lson),build(rson);
} void update(ll A,ll B,int L,int R,int l,int r,int rt){
if(R<=l||r<=L)return;
if(L<=l&&R>=r){gai(A,B,val[l]-val[L]+,rt);return;}
pushdown(rt);
int m=l+r>>;
if(L<=m) update(A,B,L,R,lson);
if(R>=m) update(A,B,L,R,rson);
pushup(rt);
} ll query(int L,int R,int l,int r,int rt){
if(R<=l||r<=L)return ;
if(L<=l&&R>=r)return t[rt].sum;
pushdown(rt);
int m=l+r>>;
ll ret=;
if(L<=m) ret+=query(L,R,lson);
if(R>=m) ret+=query(L,R,rson);
return ret;
} int main(){
n=gi(),m=gi();
For(i,,m) {
flag[i]=gi(),L[i]=gi()-,R[i]=gi(),Q[++tot]=&L[i],Q[++tot]=&R[i];
if(flag[i]==) A[i]=gi(),B[i]=gi();
}
sort(Q+,Q+tot+,cmp);
int lst=-;
For(i,,tot) if(*Q[i]!=lst) lst=*Q[i],*Q[i]=++cnt,val[cnt]=lst;else *Q[i]=cnt;
build(,cnt,);
For(i,,m)
if(flag[i]==) update(A[i],B[i],L[i],R[i],,cnt,);
else printf("%lld\n",query(L[i],R[i],,cnt,));
return ;
}

P4433 [COCI2009-2010#1] ALADIN的更多相关文章

  1. BZOJ 3090: Coci2009 [podjela]

    3090: Coci2009 [podjela] Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 23  Solved: 17[Submit][Statu ...

  2. 如何使用本地账户"完整"安装 SharePoint Server 2010+解决“New-SPConfigurationDatabase : 无法连接到 SharePoint_Config 的 SQL Server 的数据 库 master。此数据库可能不存在,或当前用户没有连接权限。”

    注:目前看到的解决本地账户完整安装SharePoint Server 2010的解决方案如下,但是,有但是的哦: 当我们选择了"完整"模式安装SharePointServer201 ...

  3. How to accept Track changes in Microsoft Word 2010?

    "Track changes" is wonderful and remarkable tool of Microsoft Word 2010. The feature allow ...

  4. [入门级] 基于 visual studio 2010 mvc4 的图书管理系统开发初步 (二)

    [入门级] 基于 visual studio 2010 mvc4 的图书管理系统开发初步 (二) Date  周六 10 一月 2015 By 钟谢伟 Category website develop ...

  5. [入门级] visual studio 2010 mvc4开发,用ibatis作为数据库访问媒介(一)

    [入门级] visual studio 2010 mvc4开发,用ibatis作为数据库访问媒介(一) Date  周二 06 一月 2015 By 钟谢伟 Tags mvc4 / asp.net 示 ...

  6. c++ builder 2010 错误 F1004 Internal compiler error at 0x9740d99 with base 0x9

    今天遇到一个奇怪的问题,拷贝项目后,在修改,会出现F1004 Internal compiler error at 0x9740d99 with base 0x9 ,不管怎么改,删除改动,都没用,关闭 ...

  7. Sharepoint 2010、Sharepoint 2013浏览器打开CAD(.dwg)

    客户端配置 1.安装FreeDWGViewer.exe,设置浏览器查看 2.检查ActiveX插件是否已安装成功 服务端配置 1.开启许可模式或者通过脚本将"application/acad ...

  8. Microsoft Windows* SDK May 2010 或较新版本(兼容 2010 年 6 月 DirectX SDK)GPU Detect

    原文链接 下载代码样本 特性/描述 日期: 2016 年 5 月 5 日 GPU Detect 是一种简短的示例,演示了检测系统中主要显卡硬件(包括第六代智能英特尔® 酷睿™ 处理器产品家族)的方式. ...

  9. delphi 2010与delphi XE破解版的冲突

    在系统中同时安装了Dephi 2010LITE版与Delphi XE lite后,总是会有一个有问题 是因为两者都是读取C:\ProgramData\Embarcadero目录下的license文件, ...

随机推荐

  1. halcon算子之tuple_gen_const,用于生成特定长度的元组并且初始化其元素

    原文地址:http://blog.sina.com.cn/s/blog_d38f8be50102wczk.html 函数原型: tuple_gen_const(: : Length, Const : ...

  2. Analysis 图标分析 - loadrunner

    analysis常见 /

  3. RAID卡的结构详解

    软件RAID的缺点如此之多,使人们不断地思考更多实现RAID的方法.既然软件缺点太多,那么用硬件实现如何呢? RAID卡就是一种利用独立硬件来实现RAID功能的方法.要在硬件上实现RAID功能,必须找 ...

  4. time命令详情

    基础命令学习目录首页 原文链接:https://blog.csdn.net/adaptiver/article/details/6596143?utm_source=blogxgwz3 linux下t ...

  5. Python从菜鸟到高手:格式化字符串

    1. 字符串格式化基础 字符串格式化相当于字符串模板.也就是说,如果一个字符串有一部分是固定的,而另一部分是动态变化的,那么就可以将固定的部分做成模板,然后那些动态变化的部分使用字符串格式化操作符(% ...

  6. sprint3(第一天)

    1.今天计划了sprint3要做的内容: 整合前台和后台,然后发布让用户使用,然后给我们反馈再进行改进 2.backlog表格: ID Name Est How to demo 1 实现用户登录与权限 ...

  7. final发布视频展示博客

    Part One [探路者]选题展示视频链接: http://v.youku.com/v_show/id_XMzIxMDM2MTQ1Ng==.html?spm=a2h3j.8428770.341605 ...

  8. 互评Beta版本-SkyHunter

    基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题;   N(Need,需求):飞机大战题材的游戏对80,90后的人来说算是童年的记忆,可以在闲暇之余打开电脑玩一会儿.但是 ...

  9. Daily Scrum (2015/11/5)

    这天晚上我们对爬虫进行了一些测试,发现仍然存在一些不小的BUG.现在我们的爬虫已经能完成基本的功能,焉域政同学也正在把他之前写的分类功能继续完善.在BUG的测试中,我们发现如果要求爬虫爬取特定的文件类 ...

  10. second scrum meeting - 151026

    摘要:这一周的工作其实进行的并没有很迅速~不过我们团队的每个人都在慢慢进行自己的工作,并且我们也完成了大致的页面设计,开发了主页面的框架,并且我们也会开始着手学习服务器的操作,还有更加完善主页面的框架 ...