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. Cilium架构 (Cilium 2)

    Cilium架构 译自:http://docs.cilium.io/en/stable/architecture/ 本文档描述了Cilium的架构.它通过记录BPF数据路径(datapath)的钩子来 ...

  2. 03-css3中的3D转换

    一.CSS3-3D转换 1.3D 特点:近大远小,物体和面遮挡不可见 1.1三维坐标系 x 轴:水平向右 -- x 轴右边是正值,左边是负值 y 轴:垂直向下 -- y 轴下面是正值,上面是负值 z ...

  3. Linux下配置mail使用外部SMTP发送邮件

    修改/etc/mail.rc,增加两行:指定外部的smtp服务器地址.帐号密码等. # vi /etc/mail.rc set from=demo@qq.com smtp=smtp.qq.com se ...

  4. S - Primitive Primes CodeForces - 1316C 数学

    数学题 在f(x)和g(x)的系数里找到第一个不是p的倍数的数,然后相加就是答案 为什么? 设x1为f(x)中第一个不是p的倍数的系数,x2为g(x)...... x1+x2前的系数为(a[x1+x2 ...

  5. H - Hamiltonian Hypercube Gym - 101170H

    规律题 首先我们要知道他的顺序是怎么来的,首先当n等于1时,是0,1 当n=2时,先按照与按顺序在他们前面分别加0,即00,01,在逆序加1,即11,10 构成的顺序为00,01,11,10:往后同理 ...

  6. 【LeetCode】57. Insert Interval [Interval 系列]

    LeetCode中,有很多关于一组interval的问题.大体可分为两类: 1.查看是否有区间重叠: 2.合并重叠区间;  3.插入新的区间: 4. 基于interval的其他问题 [ 做题通用的关键 ...

  7. vue2.x学习笔记(一)

    使用vue开发项目已经过了一段时间了,对其中的很多东西还是一知半解,于是想要系统学习一下.主要内容是参照官方中文网站https://cn.vuejs.org/v2/guide/,然后加上一些自己的理解 ...

  8. pytorch torchversion标准化数据

     新旧标准差的关系

  9. 基于Apache+Tomcat实现负载均衡

    1.基于Apache和tomcat实现负载均衡 准备三个虚拟机一个安装Apache两个安装Tomcat 关闭防火墙 systemctl stop firewalld Iptabled -F Seten ...

  10. js 函数对象的继承 inherit 带 插件完整解析版[helpers.js]

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         本篇文章为您分析一下原生JS的对象继承方法 需求分析: 1. ...