A Simple Problem with Integers

这个题目首先要打表找规律,这个对2018取模最后都会进入一个循环节,这个循环节的打表要用到龟兔赛跑。

龟兔赛跑算法 floyed判环算法

这个算法我觉得还是很有意思的,可以学习一下。

不过这个题目这个算法打表还是有点难写的。

由这个算法可以得到这个循环节的最大长度是6 最大入环距离是4.

为什么有些循环节不是6,还是可以用6呢,因为每个元素平方最大周期为6,且6是其他所有周期的公倍数。

然后学完之后还是不太会这个题目怎么写,2018 ACM-ICPC 上海大都会 H A Simple Problem with Integers(level 4)(线段树+floyd判环+暴力)

研究了一下这个人的代码,才稍微会了一点点。

这个题目首先是要判断有没有进入负环,如果一个区间的所有叶子节点都已经进入循环节,tim数组

那么这个以后就可以用延迟标记直接记录这个已经推到了这个数的循环节的第几个,mark数组

推到了循环节的第几个可以用pos数组记录,pos数组

然后就是建树,用一个二维的数组来记录,第二维是pos,代表这个数要返回的循环节的位置。

知道这些就可以自己敲代码了。

敲代码的时候越发感觉这个代码写的巧妙之处了,首先它预处理了0~2017 这样之后就可以不用求一个数的平方了,直接迭代。

然后就是这个pos数组,如果来不及push_up 就要求输出结果,这个就已经记录了,然后可以通过这个pos数组来push_up

然后就是这个树的第二维,第二维记录了从这个往后推的6个数,而且每次push_up一次就会把第二维的第一个位置更新为我们所要的结果。

这个题目很好,代码也很巧妙,值得学习。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 5e4 + ;
const int mod = ;
ll mp[maxn], a[maxn];
ll tree[maxn * ][];
int tim[maxn * ], pos[maxn * ], lazy[maxn * ]; void push_up(int id)
{
for (int i = ; i < ; i++)//这个for循环保证i==0的位置就是答案,并且推出了后面的五个位置的数
//这个的主要目的是因为只有在叶子节点的pos才会有值,只要不是叶子节点就都初始化为0,所以我们要保证tree[id][0]的位置就是答案
tree[id][i] = tree[id << ][(pos[id << ] + i) % ] + tree[id << | ][(pos[id<<|] + i) % ];
tim[id] = min(tim[id << ], tim[id << | ]);
pos[id] = ;//为什么这个地方可以赋值为0呢,因为上面的那层for循环已经保证了i==0 的位置就是答案
// printf("tree[%d][0]=%lld\n", id, tree[id][0]);
} void build(int id,int l,int r)
{
tim[id] = pos[id] = lazy[id] = ;
if(l==r)
{
tree[id][] = a[l];//一开始a[l]就是查询结果
for (int i = ; i < ; i++) tree[id][i] = mp[tree[id][i - ]];//这个就是在找a[l]的平方,a[l]平方的平方...
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
push_up(id);
} void push_down(int id)
{
pos[id << ] = (pos[id << ] + lazy[id]) % ;
pos[id << | ] = (pos[id << | ] + lazy[id]) % ;
lazy[id << ] += lazy[id];
lazy[id << | ] += lazy[id];
lazy[id] = ;
} void update(int id,int l,int r,int x,int y)
{
if (y<l || x>r) return;
if(x<=l&&y>=r&&tim[id]>)
{
lazy[id]++;
pos[id] = (pos[id] + ) % ;//为什么这个地方不求出结果,因为求不出来,这个只可以往下传递lazy 标志,并且记录这个是在循环节的哪一个位置
//然后这个位置的上一个节点被更新,或者说这个pos记录就是一种表示求结果的方式,因为之后输出的就是tree[id][pos[id]]
return;
}
if(l==r)
{
pos[id] = ;//如果还是在暴力的阶段就必须赋值为0,pos 和 lazy 只有在进入循环节之后才会有
lazy[id] = ;
tim[id]++;
tree[id][] = mp[tree[id][]];
for (int i = ; i < ; i++) tree[id][i] = mp[tree[id][i - ]];
return;
}
push_down(id);
int mid = (l + r) >> ;
if (x <= mid) update(id << , l, mid, x, y);
if (y > mid) update(id << | , mid + , r, x, y);
push_up(id);
} ll query(int id,int l,int r,int x,int y)
{
if (x > r || y < l) return ;
// printf("id=%d l=%d r=%d x=%d y=%d\n", id, l, r, x, y);
if (x <= l && y >= r) return tree[id][pos[id]];
int mid = (l + r) >> ;
push_down(id);
ll ans = ;
if (x <= mid) ans = query(id << , l, mid, x, y);
if (y > mid) ans += query(id << | , mid + , r, x, y);
return ans;
} int main()
{
for (int i = ; i < ; i++) mp[i] = i * i%mod;
int t;
scanf("%d", &t);
for(int cas=;cas<=t;cas++)
{
int n, m;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%lld", &a[i]);
build(, , n);
scanf("%d", &m);
printf("Case #%d:\n",cas);
while (m--) {
char s[];
int l, r;
scanf("%s%d%d", s, &l, &r);
if (l > r) swap(l, r);
if (s[] == 'Q') {
ll ans = query(, , n, l, r);
printf("%lld\n", ans);
}
else update(, , n, l, r);
}
}
return ;
}

A Simple Problem with Integers 循环节 修改 平方 找规律 线段树的更多相关文章

  1. poj 3468 A Simple Problem with Integers(原来是一道简单的线段树区间修改用来练练splay)

    题目链接:http://poj.org/problem?id=3468 题解:splay功能比线段树强大当然代价就是有些操作比线段树慢,这题用splay实现的比线段树慢上一倍.线段树用lazy标记差不 ...

  2. POJ-3468-A Simple Problem with Integers(区间更新,求和)-splay或线段树

    区间更新求和 主要用来练习splay树区间更新问题 //splay树的题解 // File Name: 3468-splay.cpp // Author: Zlbing // Created Time ...

  3. HDU 2522 A simple problem( 分数循环节 )

    链接:Here! 思路:模拟除法,当余数再次出现的时候一定是遇到了循环节( 可看下图例子 ),否则的话继续除法的步骤,直到被除数为 0 . 注意:这道题不需要重新申请一个数组来单独存放答案,如果符合要 ...

  4. poj3468 A Simple Problem with Integers(zkw区间修改模板)

    此题是一道线段树的裸题,这里只是为了保存我的zkw线段树模板 #include <cstdio> #include <cstring> #include <iostrea ...

  5. 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和

    poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...

  6. poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   ...

  7. A Simple Problem with Integers 多树状数组分割,区间修改,单点求职。 hdu 4267

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  8. A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 69589   ...

  9. poj 3468 A Simple Problem with Integers【线段树区间修改】

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 79137   ...

随机推荐

  1. 数据结构和算法(Golang实现)(14)常见数据结构-栈和队列

    栈和队列 一.栈 Stack 和队列 Queue 我们日常生活中,都需要将物品排列,或者安排事情的先后顺序.更通俗地讲,我们买东西时,人太多的情况下,我们要排队,排队也有先后顺序,有些人早了点来,排完 ...

  2. 【python实现卷积神经网络】上采样层upSampling2D实现

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  3. stand up meeting 11/24/2015

    part 组员 今日工作 工作耗时/h 明日计划 计划耗时/h 词典接口及数据转换 冯晓云 规范在线查词的各项请求,将返回结果解析成树状,并定义完成各种操作以方便其他部分完成调用,排序,增删等操作 3 ...

  4. PHP函数:php_sapi_name

    php_sapi_name()  - 返回 web 服务器和 PHP 之间的接口类型. SAPI(Server Application Programming Interface)服务器应用程序编程接 ...

  5. 图数据库的内部结构 (NEO4j)

    What “Graph First” Means for Native Graph Technology Neo4j是一个具有原生处理(native processing)功能和原生图存储(nativ ...

  6. 0day堆(1)堆的管理策略

    基本概念 堆块:堆区内存的基本单位 包括两个部分:块首,块身 块首:标识这个堆块自身的信息:如大小,是否被占用等 块身:分配给用户使用的数据区 堆表:一般位于堆区的起始位置,用于索引堆区所有堆块的信息 ...

  7. webug3.0靶场渗透基础Day_2(完)

    第八关: 管理员每天晚上十点上线 这题我没看懂什么意思,网上搜索到就是用bp生成一个poc让管理员点击,最简单的CSRF,这里就不多讲了,网上的教程很多. 第九关: 能不能从我到百度那边去? 构造下面 ...

  8. How to change the header background color of a QTableView

    You can set the style sheet on the QTableView ui->tableView->setStyleSheet("QHeaderView:: ...

  9. vue 开发规范

    本文档为前端 vue 开发规范 规范目的 命名规范 结构化规范 注释规范 编码规范 CSS 规范 规范目的 为提高团队协作效率 便于后台人员添加功能及前端后期优化维护 输出高质量的文档 命名规范 为了 ...

  10. Kubernetes 持久化存储是个难题,解决方案有哪些?\n

    像Kubernetes 这样的容器编排工具正在彻底改变应用程序的开发和部署方式.随着微服务架构的兴起,以及基础架构与应用程序逻辑从开发人员的角度解耦,开发人员越来越关注构建软件和交付价值. Kuber ...