注意到模数被给出且非常小,做法肯定要依赖于一些与此相关的性质。找题解打表可以发现循环节长度的lcm不超过60。

  考虑怎么用线段树维护循环。对线段树上每个点维护这段区间的循环节、在循环中的位置,如果未进入环特殊记录;每次修改对于未进入环的暴力修改,已进入环的更新在循环节上的位置即可。对于修改经过的节点暴力重构循环节。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while (c==||c==||c==) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,p,a[N];
int L[N<<],R[N<<],value[N<<][],len[N<<],pos[N<<],sum[N<<],lazy[N<<];
bool flag[N];
void up(int k)
{
int x=pos[k<<],y=pos[k<<|];
for (int i=;i<len[k];i++)
{
value[k][i]=value[k<<][x]+value[k<<|][y];
x=(x+)%len[k<<],y=(y+)%len[k<<|];
}
pos[k]=;
}
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;
if (l==r)
{
sum[k]=a[l];
int x=a[l];
while (!flag[x]) flag[x]=,x=x*x%p;
int y=a[l];
while (y!=x) pos[k]--,flag[y]=,y=y*y%p;
do
{
value[k][len[k]++]=y;
flag[y]=;
y=y*y%p;
}while (y!=x);
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
len[k]=len[k<<]*len[k<<|]/gcd(len[k<<],len[k<<|]);
pos[k]=min(pos[k<<],pos[k<<|]);
sum[k]=sum[k<<]+sum[k<<|];
if (pos[k]==) up(k);
}
void update(int k,int x){sum[k]=value[k][pos[k]=(pos[k]+x)%len[k]],lazy[k]+=x;}
void down(int k){update(k<<,lazy[k]),update(k<<|,lazy[k]),lazy[k]=;}
void modify(int k,int l,int r)
{
if (L[k]==l&&R[k]==r)
{
if (pos[k]>=) update(k,);
else if (L[k]==R[k]) sum[k]=sum[k]*sum[k]%p,pos[k]++;
else
{
pos[k]++;
if (lazy[k]) down(k);
modify(k<<,l,L[k]+R[k]>>);
modify(k<<|,(L[k]+R[k]>>)+,r);
sum[k]=sum[k<<]+sum[k<<|];
if (pos[k]==) up(k);
}
return;
}
if (lazy[k]) down(k);
int mid=L[k]+R[k]>>;
if (r<=mid) modify(k<<,l,r);
else if (l>mid) modify(k<<|,l,r);
else modify(k<<,l,mid),modify(k<<|,mid+,r);
sum[k]=sum[k<<]+sum[k<<|];
if (pos[k]>=) up(k);
}
int query(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return sum[k];
if (lazy[k]) down(k);
int mid=L[k]+R[k]>>;
if (r<=mid) return query(k<<,l,r);
else if (l>mid) return query(k<<|,l,r);
else return query(k<<,l,mid)+query(k<<|,mid+,r);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4105.in","r",stdin);
freopen("bzoj4105.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read(),p=read();
for (int i=;i<=n;i++) a[i]=read();
build(,,n);
while (m--)
{
int op=read(),l=read(),r=read();
if (op==) modify(,l,r);
else printf("%d\n",query(,l,r));
}
return ;
}

BZOJ4105 THUSC2015平方运算(线段树)的更多相关文章

  1. BZOJ 4811 树链剖分+线段树

    思路: 感觉这题也可神了.. (还是我太弱) 首先发现每一位不会互相影响,可以把每一位分开考虑,然后用树链剖分或者LCT维护这个树 修改直接修改,询问的时候算出来每一位填0,1经过这条链的变换之后得到 ...

  2. BZOJ4105 [Thu Summer Camp 2015]平方运算 【线段树】

    题目链接 BZOJ4105 题解 平方操作orz,虽说应该是线段树,但是不会维护啊QAQ 小瞧一眼题解... 平方成环?环长\(lcm\)小于\(60\)? 果然还是打表找规律题.... 那就很好做了 ...

  3. 2018.10.18 bzoj4105: [Thu Summer Camp 2015]平方运算(线段树)

    传送门 线段树妙题. 显然平方几次就会循环(打表证明不解释). 然后所有环长度的lcmlcmlcm不大于70. 因此维护一下当前区间中的节点是否全部在环上. 不是直接暴力到叶子节点修改. 否则整体打标 ...

  4. ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】

     FZU 2105  Digits Count Time Limit:10000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  5. poj 3225 线段树+位运算

    略复杂的一道题,首先要处理开闭区间问题,扩大两倍即可,注意输入最后要\n,初始化不能随便memset 采用线段树,对线段区间进行0,1标记表示该区间是否包含在s内U T S ← S ∪ T 即将[l, ...

  6. A Corrupt Mayor's Performance Art(线段树区间更新+位运算,颜色段种类)

    A Corrupt Mayor's Performance Art Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100 ...

  7. 洛谷3822 [NOI2017] 整数 【线段树】【位运算】

    题目分析: 首先这题的询问和位(bit)有关,不难想到是用线段树维护位运算. 现在我们压32位再来看这道题. 对于一个加法操作,它的添加位置可以得到,剩下的就是做不超过32的位移.这样根据压位的理论. ...

  8. hdu 5023 线段树+位运算

    主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多30颜色,那么我们可以把这30中颜色用二进制储存和传给祖先节点,二进制的每一位 ...

  9. poj 2777 Count Color - 线段树 - 位运算优化

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42472   Accepted: 12850 Description Cho ...

随机推荐

  1. 基于SpringBoot+SpringSecurity+mybatis+layui实现的一款权限系统

    这是一款适合初学者学习权限以及springBoot开发,mybatis综合操作的后台权限管理系统 其中设计到的数据查询有一对一,一对多,多对多,联合分步查询,充分利用mybatis的强大实现各种操作, ...

  2. 2019年第十届蓝桥杯c++A组java/c++组题解

    #include<iostream> #include<vector> using namespace std; vector <int > vec; long l ...

  3. SQL命令(三)

    数据完整性约束 1)数据完整性约束包含:实体完整性.参照完整性.用户定义完整性. CREATE TABLE table( id INT NOT NULL AUTO_INCREMENT PRIMARY ...

  4. PLC编码规范

    PC在编码规范方面比PLC要好很多.既然它们都是编程语言,那么PC方面的规范是否可以用与PLC呢?答案是肯定的,但需要作取舍.下面规范中的大部分可以用于一般PLC,其中有些只是针对西门子博途,使用时需 ...

  5. jenkins+maven+docker集成java发布(一)自动发布

    JAVA项目持续集成发布 标签(空格分隔): java jenkins 微服务中持续集成自动发布是很重要的一个环节,将不同的模块应用自动部署到一台或者N台服务器中如果采用人工部署的方式不太现实 git ...

  6. centos搭建SVN服务

    Linux VM_47_236_centos 3.10.0-514.21.1.el7.x86_64 需求:android.ios.service三个版本库 安装: yum -y install sub ...

  7. haproxy + keepalived 实现高可用负载均衡集群

    1. 首先准备两台tomcat机器,作为集群的单点server. 第一台: 1)tomcat,需要Java的支持,所以同样要安装Java环境. 安装非常简单. tar xf  jdk-7u65-lin ...

  8. mybatis动态列名

    mybatis动态列名 <select id="getUser" resultType="java.util.Map" parameterType=&qu ...

  9. WPF中ContextMenu(右键菜单)使用Command在部分控件上默认为灰色的处理方法

    原文:WPF中ContextMenu(右键菜单)使用Command在部分控件上默认为灰色的处理方法 问题描述 今天发现如果我想在一个TextBlock弄一个右键菜单,并且使用Command绑定,结果发 ...

  10. VS2017发布微服务到docker

    1.本文档以eShopOnContainers.sevices.identity为描述对象,并包含docker for windows的部分配置流程. 2.前置环境:win10操作系统.安装VS201 ...