ruby
Posted rlddd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby相关的知识,希望对你有一定的参考价值。
题目描述
输入一个 n 个点的无根树,初始每个节点的点权是 0。
进行 m 次操作,每次操作是三个数字 x,k,b。
具体来说就是先修改,把 x 和 x 邻接的所有点的点权,如果原先是 w i ,那么就改成 kw i + b;换句话说就是先乘以 k 再加上 b。
然后询问 x 和 x 邻接的所有点的点权和,由于结果可能很大,输出对 1000000007 取模的结果。对于 100% 的数据,满足 1 ≤ n,m ≤ 200000。
输入
第一行两个整数 n,m。
接下来 n ? 1 行描述一棵树。每行两个整数 x,y 表示 x 和 y 之间有一条边。点的下标从 1 开始。
接下来 m 行。每行三个整数 x,k,b 表示一次操作。
输出
对于每次操作输出求和取模后的结果。
样例输入
3 6
1 2
2 3
1 0 1
3 1000 0
3 1000 0
3 1000 0
3 1000 0
2 1 0
样例输出
2
1000
1000000
1000000000
999993007
999993008
题解
求出每个点的 bfs 序,使得它的所有儿子的编号连续,这样就可以在线段树上操作了。注意要判断当前节点是否有父亲,是否有儿子。
#include<queue> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=200000+50; const int p=1000000007; int n,m,x,k,b,id[maxn],fa[maxn],son[maxn],fson[maxn]; int fir[maxn],nex[maxn*2],to[maxn*2],ecnt; ll w[maxn]; bool pp[maxn]; struct node{ ll v,add,mul,l,r; } st[maxn*4]; void build(int root,ll l,ll r){ st[root].l=l;st[root].r=r; st[root].add=0;st[root].mul=1; if(l==r) st[root].v=0; else{ int m=(l+r)>>1; build(root*2,l,m); build(root*2+1,m+1,r); st[root].v=(st[root*2].v+st[root*2+1].v)%p; } } void pushdown(int root){ st[root*2].v=(st[root*2].v*st[root].mul+st[root].add*(st[root*2].r-st[root*2].l+1))%p; st[root*2+1].v=(st[root*2+1].v*st[root].mul+st[root].add*(st[root*2+1].r-st[root*2+1].l+1))%p; st[root*2].mul=(st[root*2].mul*st[root].mul)%p; st[root*2+1].mul=(st[root*2+1].mul*st[root].mul)%p; st[root*2].add=(st[root*2].add*st[root].mul+st[root].add)%p; st[root*2+1].add=(st[root*2+1].add*st[root].mul+st[root].add)%p; st[root].add=0;st[root].mul=1; } void u1(int root,ll l,ll r,ll val){ if(st[root].l>r||st[root].r<l) return ; if(st[root].l>=l&&st[root].r<=r){ st[root].v=(st[root].v*val)%p; st[root].add=(st[root].add*val)%p; st[root].mul=(st[root].mul*val)%p; } else{ pushdown(root); u1(root*2,l,r,val); u1(root*2+1,l,r,val); st[root].v=(st[root*2].v+st[root*2+1].v)%p; } } void u2(int root,ll l,ll r,ll val){ if(st[root].l>r||st[root].r<l) return ; if(st[root].l>=l&&st[root].r<=r){ st[root].v=(st[root].v+val*(st[root].r-st[root].l+1))%p; st[root].add=(st[root].add+val)%p; } else{ pushdown(root); u2(root*2,l,r,val); u2(root*2+1,l,r,val); st[root].v=(st[root*2].v+st[root*2+1].v)%p; } } ll query(int root,ll l,ll r){ if(st[root].l>r||st[root].r<l) return 0; if(st[root].l>=l&&st[root].r<=r) return st[root].v; else{ pushdown(root); return (query(root*2,l,r)+query(root*2+1,l,r))%p; } } void add(int u,int v){ nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v; } void bfs() { queue<int> q; int tot=0; q.push(1); while(!q.empty()) { int x=q.front(); id[x]=++tot; q.pop(); for(int e=fir[x];e;e=nex[e]) if(to[e]!=fa[x]) { son[x]++; if(son[x]==1) fson[x]=to[e]; fa[to[e]]=x; q.push(to[e]); } } } template<typename T>void read(T& aa){ char cc; ll ff;aa=0;cc=getchar();ff=1; while((cc<‘0‘||cc>‘9‘)&&cc!=‘-‘) cc=getchar(); if(cc==‘-‘) ff=-1,cc=getchar(); while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar(); aa*=ff; } int main(){ freopen("ruby.in","r",stdin); freopen("ruby.out","w",stdout); read(n),read(m); build(1,1,n); for(int i=1;i<n;i++){ int x,y; read(x),read(y); add(x,y),add(y,x); } bfs(); while(m--){ int x,k,b;ll ans=0; read(x),read(k),read(b); u1(1,id[x],id[x],k); u2(1,id[x],id[x],b); ans+=query(1,id[x],id[x]); if(son[x]){ u1(1,id[fson[x]],id[fson[x]]+son[x]-1,k); u2(1,id[fson[x]],id[fson[x]]+son[x]-1,b); ans=(ans+query(1,id[fson[x]],id[fson[x]]+son[x]-1))%p; } if(fa[x]){ u1(1,id[fa[x]],id[fa[x]],k); u2(1,id[fa[x]],id[fa[x]],b); ans=(ans+query(1,id[fa[x]],id[fa[x]]))%p; } printf("%lld ",ans); } return 0; }
以上是关于ruby的主要内容,如果未能解决你的问题,请参考以下文章