3494. 【NOIP2013模拟联考13】线段(segment) (2017.9B组)
2017-10-07 22:32
423 查看
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
线段树最好把多个操作分类,合在一起打会好调很多
数轴上有很多单位线段,一开始时所有单位线段的权值都是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 long using 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 4000 ,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); } } }
相关文章推荐
- 高中OJ3494. 【NOIP2013模拟联考13】线段(segment)
- 【NOIP2013模拟联考13】线段
- [jzoj3472]【NOIP2013模拟联考8】匹配(match)
- 【NOIP2013模拟联考5】军训(training)
- 【NOIP2013模拟联考3】山峰(summits)
- JZOJ 3468. 【NOIP2013模拟联考7】OSU!(osu)
- 【NOIP2013模拟联考5】军训(training) 题解+代码
- NOIP2013模拟联考5】军训(training)
- JZOJ3456. 【NOIP2013模拟联考3】恭介的法则(rule)(2017.8B组)
- [jzoj]3498. 【NOIP2013模拟联考14】图形变换(transform) (计算几何+矩阵乘法)
- 【NOIP2013模拟联考7】数列
- JZOJ3457. 【NOIP2013模拟联考3】沙耶的玩偶(doll) (2017.8B组)
- jzoj 3467. 【NOIP2013模拟联考7】最长上升子序列(lis) dfs+lis+手工栈
- 【NOIP2013模拟联考5】军训(training) 题解
- [jzoj]3499. 【NOIP2013模拟联考15】人类基因组(genes) (单调队列、前缀和、线段树解一题)
- JZOJ 3447【NOIP2013模拟联考2】摘取作物
- 【NOIP2013模拟联考2】摘取作物(pick)
- JZOJsenior3455.【NOIP2013模拟联考3】库特的向量(code)
- 3450. 【NOIP2013模拟联考3】山峰(summits) (Standard IO)
- 3486. 【NOIP2013模拟联考10】道路改建(rebuild)(2017.12A组)(tarjan缩环+拓补排序+DP+bitset)