UOJ

思路

模拟赛出了这题,结果我没学过二进制分组……一波主席树然后空间就爆炸了……

用线段树维护时间序列,每个节点维护\(a_i\to x_i\times a_i+b_i,i\in [1,n]\)的信息。由于每次加入一个操作只会加入两个断点,所以维护数列上每个线段的二元组\((a,b)\)。

当一个时间块被填满之后就把两边的二元组归并上来,复杂度是\(O(断点个数)\)。

由于一个操作只会加2个断点,一个断点只会被往上合并\(O(\log n)\)次,所以复杂度非常正确。

询问的时候在线段树上找到区间,然后在每个区间的数轴上二分得到要问的那一个点。

(感觉讲的不是很清晰,但代码很好看懂)

(这简直就像是个暴力,但它就是对的……)

(另外我模拟赛的做法:发现二元组一般是有可减性的,所以用主席树维护经过前面几次操作之后每个位置的二元组。然而空间就爆炸了……)

代码

#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 101010
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char __sr[1<<21],__z[20];int __C=-1,__zz=0;
inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
inline void print(register int x)
{
if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
while(__z[++__zz]=x%10+48,x/=10);
while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
}
void file()
{
#ifdef NTFOrz
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifdef NTFOrz
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n;ll mod;int m;
int a[sz]; struct hh{ll a,b;int r;hh(ll A=1,ll B=0,int R=0){a=A,b=B,r=R;}const hh operator * (const hh &x) const {return hh(a*x.a%mod,(b*x.a+x.b)%mod,min(r,x.r));}};
int T;
vector<hh>tr[sz<<2];
#define ls k<<1
#define rs k<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
void addtag(int k,int l,int r,int a,int b){if (l!=1) tr[k].push_back(hh(1,0,l-1));tr[k].push_back(hh(a,b,r));if (r!=n) tr[k].push_back(hh(1,0,n));}
void merge(vector<hh> &tr,const vector<hh> &L,const vector<hh> &R)
{
int s1=L.size(),s2=R.size();
int p=0,q=0;
while (p<s1&&q<s2)
{
tr.push_back(L[p]*R[q]);
if (L[p].r==R[q].r) ++p,++q;
else L[p].r<R[q].r?++p:++q;
}
}
void modify(int k,int l,int r,int x,int y,int a,int b)
{
if (l==r) return addtag(k,x,y,a,b);
int mid=(l+r)>>1;
if (T<=mid) modify(lson,x,y,a,b); else modify(rson,x,y,a,b);
if (T==r) merge(tr[k],tr[ls],tr[rs]);
}
ll ans;
void calc(int k,int p)
{
int l=0,r=(int)tr[k].size()-1,mid,pos=0;
while (l<=r) tr[k][mid=(l+r)>>1].r>=p?pos=mid,r=mid-1:l=mid+1;
ans=(ans*tr[k][pos].a%mod+tr[k][pos].b)%mod;
}
void query(int k,int l,int r,int x,int y,int p)
{
if (x<=l&&r<=y) return calc(k,p);
int mid=(l+r)>>1;
if (x<=mid) query(lson,x,y,p);
if (y>mid) query(rson,x,y,p);
} int main()
{
file();
int type;read(type);type&=1;
read(n),read(mod);
rep(i,1,n) read(a[i]);
read(m);
rep(t,1,m)
{
int opt,l,r,x,y;
read(opt),read(l),read(r),read(x);if (opt==1) read(y);
if (opt==1)
{
if (type) l^=ans,r^=ans;
if (l>r) swap(l,r);
++T;modify(1,1,1e5,l,r,x,y);
}
else
{
if (type) l^=ans,r^=ans,x^=ans;
if (l>r) swap(l,r);
ans=a[x];query(1,1,1e5,l,r,x);
printf("%lld\n",ans);
}
}
}

UOJ46. 【清华集训2014】玄学 [线段树,二进制分组]的更多相关文章

  1. UOJ46 清华集训2014玄学(线段树)

    注意到操作有结合律,容易想到用一个矩形表示第i次操作对第j个位置的数的影响.那么修改是单行内的区间修改,而查询是单列内的区间查询.这样二维线段树上以列为外层行为内层直接打标记就可以维护.然后就喜闻乐见 ...

  2. [UOJ46][清华集训2014]玄学

    uoj description 给出\(n\)个变换,第\(i\)个变换是将区间中\(l_i,r_i\)的数\(x\)变成\((a_ix+b_i)\mod m\). 每次会新增一个变换,或者查询询问如 ...

  3. 【题解】P4247 [清华集训]序列操作(线段树修改DP)

    [题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...

  4. 【uoj#46】 [清华集训2014] 玄学

      题目传送门:uoj46   题意简述:要求在序列上维护一个操作间支持结合律的区间操作,查询连续一段时间内的操作对单点的作用效果,\(n \leq 10^5,m \leq 6 \times 10^5 ...

  5. 【uoj#164】[清华集训2015]V 线段树维护历史最值

    题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...

  6. UOJ #164 [清华集训2015]V (线段树)

    题目链接 http://uoj.ac/problem/164 题解 神仙线段树题. 首先赋值操作可以等价于减掉正无穷再加上\(x\). 假设某个位置从前到后的操作序列是: \(x_1,x_2,..., ...

  7. uoj #46[清华集训2014]玄学

    uoj 因为询问是关于一段连续区间内的操作的,所以对操作构建线段树,这里每个点维护若干个不交的区间,每个区间\((l,r,a,b)\)表示区间\([l,r]\)内的数要变成\(ax+b\) 每次把新操 ...

  8. uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题

    [清华集训2014]矩阵变换 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出 ...

  9. AC日记——【清华集训2014】奇数国 uoj 38

    #38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘 ...

随机推荐

  1. easyUi——datetimebox绑定数据失效

    在做easy-ui时候,绑定数据不管在怎么写,都绑定不上去,最后发现是因为 标签的ID没有写,尴尬了,记录一下,防止后期出错. ui代码 <script type="text/java ...

  2. 【转载】C#中使用int.Parse方法将字符串转换为整型Int类型

    在C#编程过程中,很多时候涉及到数据类型的转换,例如将字符串类型的变量转换为Int类型就是一个常见的类型转换操作,int.Parse方法是C#中专门用来将字符串转换为整型int的,int.Parse方 ...

  3. 学习笔记之DBeaver

    DBeaver Community | Free Universal Database Tool https://dbeaver.io/ Universal Database Tool Free mu ...

  4. Celery:First Steps

    参考文档:http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html#first-step ...

  5. scrapy爬虫中间件-urlLength

    浏览器里面能输入的最大url是有限制的 safari 最多 一万多 ie最少  2083 urllength中间件源码 谷歌和火狐正常 八千多 """ Url Lengt ...

  6. PDF 补丁丁 0.6.2 测试版发布

    如题. 不知不觉,这个软件已经出来十个年头了. 0.6.2 版可能是 PDF 补丁丁的最后一版.它在未来将不再更新.谢谢关注.

  7. day 09 预科

    目录 函数 定义函数 函数定义的三种形式 空函数 有参函数(有参数()的函数) 无参函数 函数的返回值 函数的参数 形参 位置形参 实参 位置实参 关键字实参 函数 def twoSum(nums,t ...

  8. 函数式接口(Functional Interface)

    原文链接:https://www.cnblogs.com/runningTurtle/p/7092632.html 阅读目录 什么是函数式接口(Functional Interface) 函数式接口用 ...

  9. mysql备份脚本(基础版)

    #!/bin/bash #authors misery # BAK_DIR=/home/web_code1/backup/mysql_backup/`date +%Y-%m-%d` MYSQL_CMD ...

  10. 万众期待的kintone开发账号免费开放申请啦!

    亲爱的小伙伴们,等了很久很久的kintone开发账号终于可以免费申请使用了! 有人想问了,什么是kintone? kintone是指无需开发知识,即可根据公司业务轻松创建系统的Cybozu的云服务. ...