https://vjudge.net/problem/CodeForces-498D

http://codeforces.com/problemset/problem/498/D

题面描述:

一些国家由(n + 1)个城市组成,位于一条直路上。我们用连续的整数从1到n + 1按照高速公路上出现的顺序对城市进行编号。因此,城市由高速公路的n段连接起来,第i段连接城市i和i + 1。高速公路的每一段都与一个正整数ai相关联 - 表示何时交通拥堵期出现在该段上。

为了从城市x到城市y(x <y),一些司机使用以下策略。

最初驾驶员在城市x,当前时间t等于0。在驾驶员抵达城市之前,他会采取以下行动:

1.如果当前时间t是ax的倍数,那么高速公路号x的段现在有交通问题,驾驶员在当前城市停留一个单位时间(当前t = t + 1)。

2.如果当前时间t不是ax的倍数,那么高速公路号x的段现在是畅通的,驾驶员使用一个单位时间移动到城市x + 1(当前t = t + 1且x = x + 1)。

你正在开发一个新的交通控制系统。您要连续处理两种类型的q查询:

A:我们应用上面描述的策略,确定从城市x到城市y(x <y)之后的时间t的最终值。请注意,对于每个查询t初始值为0。

C:用值y替换出现在段号x上的堵塞时段(令ax = y)。

Input
10
2 5 3 2 3 5 3 4 2 4
10
C 10 6
A 2 6
A 1 3
C 3 4
A 3 11
A 4 9
A 5 6
C 7 3
A 8 10
A 2 5
Output
5
3
14
6
2
4
4

这道题还是不是那么好想的……

我们需要发现一个性质:对于0s和60s来说,我们只要走相同的路得到的时间%60都是一样的。

(原因很简单,2-6最小公倍数为60)

所以我们开线段树tree[i][j]表示i区间从js(0<=j<60)开始从头走到尾的最终时间。

build的时候公式如下:

tree[a][i]=tree[a*2+1][tree[a*2][i]%tmax]+tree[a*2][i]/tmax*tmax;

gai的时候和build差不多。

询问的话……看代码吧。

(祝贺60棵线段树AC第一道CF题)

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
inline int read(){
int X=,w=; char ch=;
while(ch<''||ch>'') {if(ch=='-') w=-;ch=getchar();}
while(ch>=''&&ch<='') X=(X<<)+(X<<)+ch-'',ch=getchar();
return X*w;
}
const int tmax=;
int tree[][tmax];
int b[];
void build(int a,int l,int r){
if(l==r){
   for(int i=;i<tmax;i++){
   if(i%b[l])tree[a][i]=i+;
   else tree[a][i]=i+;
   }
return;
}
int mid=(l+r)>>;
build(a*,l,mid);
build(a*+,mid+,r);
for(int i=;i<tmax;i++){
   tree[a][i]=tree[a*+][tree[a*][i]%tmax]+tree[a*][i]/tmax*tmax;
}
return;
}
int check(int a,int l,int r,int l1,int r1,int t){
if(l>r1||r<l1)return t;
if(l1<=l&&r<=r1){
  return tree[a][t%tmax]+t/tmax*tmax;
}
int mid=(l+r)>>;
int k1=check(a*,l,mid,l1,r1,t);
int k2=check(a*+,mid+,r,l1,r1,k1);
return k2;
}
void gai(int a,int l,int r,int x,int y){
if(x<l||r<x)return;
if(l==x&&x==r){
   b[l]=y;
for(int i=;i<tmax;i++){
   if(i%b[l])tree[a][i]=i+;
   else tree[a][i]=i+;
   }
  return;
}
int mid=(l+r)>>;
gai(a*,l,mid,x,y);
gai(a*+,mid+,r,x,y);
for(int i=;i<tmax;i++){
  tree[a][i]=tree[a*+][tree[a*][i]%tmax]+tree[a*][i]/tmax*tmax;
}
return;
}
int main(){
int n=read();
for(int i=;i<=n;i++){
  b[i]=read();
}
build(,,n);
int q=read();
for(int i=;i<=q;i++){
  char c;
   cin>>c;
   int x=read();
  int y=read();
   if(c=='A'){
   printf("%d\n",check(,,n,x,y-,));
   }else{
   gai(,,n,x,y);
   }
}
return ;
}

最新文章

  1. 三种经典iPhone上网络抓包方法详解
  2. subtable
  3. 基于MVC4+EasyUI的Web开发框架形成之旅--权限控制
  4. Python--关于dict
  5. Codeforces Round #337 (Div. 2) A. Pasha and Stick 水题
  6. nginx定时备份access访问日志并重启nginx
  7. Python异常处理 分类: python Raspberry Pi 服务器搭建 2015-04-01 13:22 172人阅读 评论(0) 收藏
  8. linux sort,uniq,cut,wc命令详解 (转)
  9. jQuery学习笔记一
  10. macbook air扩展显示器全屏滑动怎样不一起滑动?
  11. qt 共享内存 单例
  12. Java_监听器监听文件夹变动
  13. Going Home HDU - 1533 费用流
  14. Kotlin入门(20)几种常见的对话框
  15. 单色液晶模块推荐LM6800
  16. React Native 炫酷的动画库 实现任何AE动画 lottie-react-native
  17. fonts.googleapis.com 字体报错问题解决。
  18. Springboot listener
  19. CentOS 6.8 ftp服务安装配置 基于本地用户和虚拟用户
  20. Okhttp常用方法示例

热门文章

  1. NSNull Crash处理 (NullSafe 的原理)
  2. andriod学习一
  3. libevent学习一
  4. [USACO09Open] Tower of Hay 干草塔
  5. Angualr6访问API
  6. mpvue笔记
  7. Simple layout
  8. 蓝牙ble数据转语音实现Android AudioRecord方法推荐
  9. 在JS中 实现不用中间变量temp 实现两个变量值得交换
  10. python执行linux命令的两种方法