3494. 【NOIP2013模拟联考13】线段(segment) (2017.9B组)
来源:互联网 发布:淘宝广场舞服装春装 编辑:程序博客网 时间:2024/04/30 16:06
Description
数轴上有很多单位线段,一开始时所有单位线段的权值都是1。有两种操作,第一种操作将某一区间内的单位线段权值乘以w,第二种操作将某一区间内的单位线段权值取w次幂。并且你还需要回答一些询问,每个询问需要求出某一区间的单位线段权值之积。由于答案可能很大,你只需要求出答案 mod (10^9+7)的值。
说明:n个点只有n-1条线段。
Input
第一行一个整数n,表示操作数量。
接下来n行,每行第一个整数表示操作类型,0表示第一种操作,1表示第二种操作,2表示询问,如果第一个数是0或1,则接下来3个数,表示操作区间和w,否则接下来两个数,表示询问区间。
Output
对于每组询问,输出一行,表示所求答案。
Sample Input
7
0 0 2 3
1 1 3 2
2 1 3
0 0 3 2
1 1 3 2
2 1 3
2 0 3
Sample Output
9
1296
7776
想法:
第一次接触动态开点线段树
其实比较简单啦
只不过是如果有需要的话给某个节点赋予它儿子而已
这道题
下传两个lazy标记
先^a,再乘b
下传标记^a*b,至^c *d
c=c*a
d=d^a*b
细节较多
code
线段树最好把多个操作分类,合在一起打会好调很多
#include <cstdio>#include <cstring>#include <iostream>#define ll long longusing namespace std;const ll maxn=1e9+7,maxN=2e6,max1=1e9+7;struct zhj{ ll l,r,ans,mi,cheng; };ll q,i,x1,tot,ans,zl,y1,z1;zhj tree[maxN];ll ksm(ll x,ll y){ ll k=1,z=x%maxn; y%=maxn-1; while (y>0) { if (y&1==1) k=(k*z)%maxn; y>>=1; z=(z*z)%maxn; } return k;} void xg(ll x,ll l,ll r,ll a,ll b){ tree[x].ans=(ksm(tree[x].ans,a)*ksm(b,r-l+1))%maxn; tree[x].mi=(tree[x].mi*a)%(maxn-1); tree[x].cheng=(ksm(tree[x].cheng,a)*b)%maxn; return;}void change(ll x,ll head,ll tail,ll l,ll r,ll zl,ll y){ if ((head==l)&&(tail==r)) { if (zl==1) { tree[x].ans=(tree[x].ans*ksm(y,tail-head+1))%maxn; tree[x].cheng=(tree[x].cheng*y)%maxn; } if (zl==2) { tree[x].ans=ksm(tree[x].ans,y); tree[x].mi=(tree[x].mi*y)%(maxn-1); tree[x].cheng=ksm(tree[x].cheng,y)%maxn; } if (zl==3) { ans=(ans*tree[x].ans)%maxn; } return; } ll mid=(head+tail)/2,l1,r1; if (tree[x].l>0) l1=tree[x].l; else tot++,tree[x].l=tot,l1=tot,tree[l1].ans=1,tree[l1].cheng=1,tree[l1].mi=1; if (tree[x].r>0) r1=tree[x].r; else tot++,tree[x].r=tot,r1=tot,tree[r1].ans=1,tree[r1].cheng=1,tree[r1].mi=1;; tree[x].mi%=maxn-1; xg(l1,head,mid,tree[x].mi,tree[x].cheng); xg(r1,mid+1,tail,tree[x].mi,tree[x].cheng); tree[x].mi=1; tree[x].cheng=1; if (r<=mid) change(l1,head,mid,l,r,zl,y); else if (l>mid) change(r1,mid+1,tail,l,r,zl,y); else { change(l1,head,mid,l,mid,zl,y); change(r1,mid+1,tail,mid+1,r,zl,y); } tree[x].ans=(tree[l1].ans*tree[r1].ans)%maxn;}int main(){ freopen("segment.in","r",stdin); freopen("segment.out","w",stdout); tot=1; tree[1].cheng=1; tree[1].mi=1; scanf("%lld",&q); for (i=1;i<=q;i++) { scanf("%lld",&zl); if (zl==0) { scanf("%lld%lld%lld",&x1,&y1,&z1); y1--; change(1,1,max1+max1,x1+max1,y1+max1,1,z1); } if (zl==1) { scanf("%lld%lld%lld",&x1,&y1,&z1); y1--; change(1,1,max1+max1,x1+max1,y1+max1,2,z1%(maxn-1)); } if (zl==2) { scanf("%lld%lld",&x1,&y1); y1--; ans=1; change(1,1,max1+max1,max1+x1,y1+max1,3,0); printf("%lld\n",ans); } }}
阅读全文
0 0
- 3494. 【NOIP2013模拟联考13】线段(segment) (2017.9B组)
- 高中OJ3494. 【NOIP2013模拟联考13】线段(segment)
- 【NOIP2013模拟联考13】线段
- JZOJ3456. 【NOIP2013模拟联考3】恭介的法则(rule)(2017.8B组)
- JZOJ3457. 【NOIP2013模拟联考3】沙耶的玩偶(doll) (2017.8B组)
- [jzoj]3499. 【NOIP2013模拟联考15】人类基因组(genes) (单调队列、前缀和、线段树解一题)
- [jzoj]3480. 【NOIP2013模拟联考9】阿Q的停车场(park)(线段树+堆)
- 【NOIP2013模拟联考7】数列
- 【NOIP2013模拟联考5】军训
- 【NOIP2013模拟联考6】选课
- 【NOIP2013模拟联考7】OSU
- SSL2864 【NOIP2013模拟联考15】物语(spfa优化)
- 【NOIP2013模拟联考12】数数(数位dp||类欧几里得)
- JZOJ3425. 【NOIP2013模拟】能量获取(2017.8B组)
- JZOJ3426. 【NOIP2013模拟】封印一击 (2017.8B组)
- JZOJ3427. 【NOIP2013模拟】归途与征程 (2017.8B组)
- 【NOIP2013模拟联考5】军训(training)
- 【NOIP2013模拟联考6】选课(select)
- 349_LeetCode_349 Intersection of Two Arrays 题解
- web页面渲染
- java程序员面试宝典1
- CF272C Dima and Staircase(线段树/贪心)
- 学习资源推荐(不定期更新)
- 3494. 【NOIP2013模拟联考13】线段(segment) (2017.9B组)
- MySQL基础教程之存储过程
- Jzoj4614 字符串(待填)
- c\c++中的数据输入
- Android Studio+Appium+Java+Windows环境安装搭建
- JavaScript代码实现选水果
- Unity_版本切换_预编译手段
- 2017/10/7
- 零基础入门深度学习(3)