填坑

我不知道怎么算的,但是所有环的LCM数不会超过60

然后用线段树维护这个东西,每个节点记录子树内的循环节

没到循环节的暴力枚举

复杂度是nlogn再乘以循环节长度

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector> #define lc (now<<1)
#define rc (now<<1|1)
#define mid (ql+qr)/2
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=1e5+_;
const int maxp=1e4+_;
const int maxh=+;
const int mbit=(<<)+_;
int gcd(int a,int b){if(a==)return b;return gcd(b%a,a);}
int lcm(int a,int b){return a/gcd(a,b)*b;} int nxt[maxp];bool inh[maxp];int tim,v[maxp];
void init(int p)
{
for(int i=;i<p;i++)nxt[i]=i*i%p;
tim=;
for(int i=;i<p;i++)
if(v[i]==)
{
v[i]=++tim;
for(int k=nxt[i];;k=nxt[k])
{
if(v[k]==tim)
{
inh[k]=true;
for(int u=nxt[k];u!=k;u=nxt[u])inh[u]=true;
break;
}
if(v[k]>)break;
v[k]=tim;
}
}
} //--------------------------------------yu--------------------------------------------------- struct hh
{
int len,pos,h[maxh];
hh(){}
int insert(int d)
{
if(inh[d])
{
len=;pos=;h[++len]=d;
for(int k=nxt[d];k!=d;k=nxt[k])h[++len]=k;
return ;
}
return -;
}
void merge(hh h1,hh h2)
{
len=lcm(h1.len,h2.len);pos=;
for(int k=,i=h1.pos,j=h2.pos;k<=len;k++,i=i%h1.len+,j=j%h2.len+)
h[k]=h1.h[i]+h2.h[j];
}
int ad(int b){pos=(pos+b-)%len+;return h[pos];}
};
struct trnode{int sum,la;hh h;};int w[maxn];
struct Segtree
{
trnode tr[*mbit];
Segtree(){}
void update(int now)
{
tr[now].sum=tr[lc].sum+tr[rc].sum;
if(tr[lc].la!=-&&tr[rc].la!=-)
{
tr[now].la=;
tr[now].h.merge(tr[lc].h,tr[rc].h);
}
else tr[now].la=-;
}
void pushdown(int now)
{
if(tr[now].la<=)return ;
tr[lc].sum=tr[lc].h.ad(tr[now].la),tr[lc].la=(tr[lc].la+tr[now].la-)%tr[lc].h.len+;
tr[rc].sum=tr[rc].h.ad(tr[now].la),tr[rc].la=(tr[rc].la+tr[now].la-)%tr[rc].h.len+;
tr[now].la=;
}
void bt(int now,int ql,int qr)
{
if(ql==qr){tr[now].sum=w[ql],tr[now].la=tr[now].h.insert(w[ql]);return ;}
bt(lc,ql,mid),bt(rc,mid+,qr),update(now);
}
void change(int now,int ql,int qr,int l,int r)
{
if(ql==l&&qr==r&&tr[now].la!=-){tr[now].sum=tr[now].h.ad();tr[now].la++;return ;}
if(ql==qr){tr[now].la=tr[now].h.insert(nxt[tr[now].sum]),tr[now].sum=nxt[tr[now].sum];return ;}
pushdown(now);
if(r<=mid) change(lc,ql,mid,l,r);
else if(mid+<=l)change(rc,mid+,qr,l,r);
else change(lc,ql,mid,l,mid),change(rc,mid+,qr,mid+,r);
update(now);
}
int getsum(int now,int ql,int qr,int l,int r)
{
if(ql==l&&qr==r)return tr[now].sum;
pushdown(now);
if(r<=mid) return getsum(lc,ql,mid,l,r);
else if(mid+<=l)return getsum(rc,mid+,qr,l,r);
else return getsum(lc,ql,mid,l,mid)+getsum(rc,mid+,qr,mid+,r);
}
}S; //---------------------------------data structure--------------------------------------------- int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int n,Q,p;
scanf("%d%d%d",&n,&Q,&p);
init(p); for(int i=;i<=n;i++)scanf("%d",&w[i]);
S.bt(,,n); int op,x,y;
while(Q--)
{
scanf("%d%d%d",&op,&x,&y);
if(op==)S.change(,,n,x,y);
else printf("%d\n",S.getsum(,,n,x,y));
} return ;
}

bzoj4105: [Thu Summer Camp 2015]平方运算的更多相关文章

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

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

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

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

  3. bzoj:4105: [Thu Summer Camp 2015]平方运算

    Description   Input 第一行有三个整数N,M,p,分别代表序列的长度.平方操作与询问操作的总次数以及在平方操作中所要模的数.   接下来一行N个数代表一开始的序列{X1,X2,... ...

  4. 4105: [Thu Summer Camp 2015]平方运算

    首先嘛这道题目只要知道一个东西就很容易了:所有循环的最小公约数<=60,成一条链的长度最大为11,那么我们就可以用一个很裸的方法.对于在链上的数,我们修改直接暴力找出并修改.对于在环上的数,我们 ...

  5. [Thu Summer Camp 2015]解密运算

    4104: [Thu Summer Camp 2015]解密运算 Time Limit: 10 Sec  Memory Limit: 512 MB Description 对于一个长度为N的字符串,我 ...

  6. 【BZOJ 4104】 4104: [Thu Summer Camp 2015]解密运算 (智商)

    4104: [Thu Summer Camp 2015]解密运算 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 370  Solved: 237 De ...

  7. BZOJ4104:[Thu Summer Camp 2015]解密运算——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4104 对于一个长度为N的字符串,我们在字符串的末尾添加一个特殊的字符".".之 ...

  8. BZOJ4104 [Thu Summer Camp 2015]解密运算 【乱搞】

    题目链接 BZOJ4104 题解 我们将已知字符排序,由循环就可以得到一个对应关系 如样例就是: 0->第5行 1->第1行 1->第2行 1->第3行 1->第5行 2 ...

  9. bzoj 4104 [Thu Summer Camp 2015]解密运算——思路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4104 想了很久,想出一个 nlogn (也许是 n2logn )的,可惜空间是 n2 . 已 ...

随机推荐

  1. Admin组件-----Django自带

    1 list_display from django.contrib import admin # Register your models here. from app01.models impor ...

  2. hdu 1166 树状数组(线段树)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. EC++学习笔记(四) 设计与声明

    条款18:让接口容易被正确使用,不易被误用 必须考虑客户可能做出什么样的错误(防御式编程)std:shared_ptr会自动使用它的"每个指针专属的删除器",消除了"cr ...

  4. CF 527C Glass Carving

    数据结构维护二维平面 首先横着切与竖着切是完全没有关联的, 简单贪心,最大子矩阵的面积一定是最大长*最大宽 此处有三种做法 1.用set来维护,每次插入操作寻找这个点的前驱和后继,并维护一个计数数组, ...

  5. C++ 中new

    operator new在C++中的各种写法 (2011-09-21 14:59:33) 标签: 杂谈   乍一看,在C++中动态分配内存很简单:new是分配,delete是释放,就这么简单.然而,这 ...

  6. Laravel 视图中的url

    <a href="{{ url('url') }}">url</a> <a href="{{ action('StudentControll ...

  7. SGU101 求有重边的无向图欧拉迹

    题意:好多木棒,俩端有数字(0--6)标记,按数字相同的端首尾相连成一条直线(木棒可以相同).即求有重边的无向图欧拉迹. 先判定是否为欧拉图,俩个条件,不说了.如果是欧拉图,输出路经. 方法:dfs遍 ...

  8. Codeforces 864E Fire(DP)

    题目链接 Fire 题意 有n个物品,每个物品的挽救时间代价为ti, 消失时刻为di, 价值为pi. 如果要救某个物品,必须在他消失之前救出来. 同一时刻最多只能救一件物品. 当前耗时为当前已经救出的 ...

  9. [bzoj1110][POI2007]砝码Odw_贪心

    bzoj-1110 POI-2007 砝码Odw 参考博客:http://hzwer.com/4761.html 题目大意:在byteotian公司搬家的时候,他们发现他们的大量的精密砝码的搬运是一件 ...

  10. 某考试 T1 function

    (数据范围 n<=10^9 ,T<=10 ) 首先,我来证明一下 Σμ(d) * σ(i/d)^2 = σ(i^2) 相信做过约数个数和的童鞋都可以完成从右式推到左式,那么我现在就说一下怎 ...