NC202310. A Simple Problem On A Tree
描述
输入描述
The first line of the input gives the number of test case, (). test cases follow.
For each case, the first line contains only one integer .() The next lines each contains two integers , which means there is an edge between them. It also means we will give you one tree initially.
The next line will contains integers which means the initial weight of each node. ()The next line will contains an integer . () The next lines will start with an integer 1, 2, 3 or 4 means the kind of this operation.1.Given three integers , , , for the , and all nodes between the path from to inclusive, you should update their weight to . (, )
2.Given three integers , , , for the , and all nodes between the path from to inclusive, you should increase their weight by . (, )
3. Given three integers , , , for the , and all nodes between the path from to inclusive, you should multiply their weight by . (, )
4.Given two integers , , you should check the node weights on the path between and , and you should output cubic sum of them. It means, output , is node on the path from to (inclusive and ). ()
输出描述
For each test case, output one line containing ``Case #x:'', where x is the test case number (starting from 1).
For operation 4, output a single integer in one line representing the result. The result could be huge, print it module 1,000,000,007.
示例1
输入:
1 5 2 1 1 3 5 3 4 3 1 2 3 4 5 6 4 2 4 1 5 4 2 2 2 4 3 3 2 3 4 4 5 4 4 2 4
输出:
Case #1: 100 8133 20221
C++(clang++11) 解法, 执行用时: 2325ms, 内存消耗: 30588K, 提交时间: 2020-12-09 17:53:07
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7; #define mst(a,b) memset(a,b,sizeof a) #define PII pair<int,int> #define fi first #define se second #define pb push_back #define lx x<<1 #define rx x<<1|1 int fa[N],son[N],top[N],sz[N],dfn[N],rk[N],dep[N],w[N]; vector<int>e[N]; int T,n,Q,tim; struct node{ int l,r; ll ad,mu,s1,s2,s3; }a[N<<2]; void dfs(int u,int f){ sz[u]=1,fa[u]=f,dep[u]=dep[f]+1,son[u]=0; for(int v:e[u]){ if(v==f) continue; dfs(v,u),sz[u]+=sz[v]; if(sz[son[u]]<sz[v]) son[u]=v; } } void dfs1(int u,int t){ top[u]=t,dfn[u]=++tim,rk[tim]=u; if(son[u]) dfs1(son[u],t); for(int v:e[u]){ if(v==fa[u]||v==son[u]) continue; dfs1(v,v); } } void re(int x){ a[x].s1=(a[lx].s1+a[rx].s1)%mod; a[x].s2=(a[lx].s2+a[rx].s2)%mod; a[x].s3=(a[lx].s3+a[rx].s3)%mod; } void bud(int x,int l,int r){ a[x].l=l,a[x].r=r,a[x].mu=1,a[x].ad=0; if(l==r){ ll y=w[rk[l]]; a[x].s1=y%mod; a[x].s2=a[x].s1*y%mod; a[x].s3=a[x].s2*y%mod;return; }int mid=l+r>>1; bud(lx,l,mid),bud(rx,mid+1,r),re(x); } void phd1(int x,int s,ll c){ ll mu=a[x].mu,ad=a[x].ad; a[s].mu=a[s].mu*mu%mod,a[s].ad=a[s].ad*mu%mod,a[s].ad=(a[s].ad+ad)%mod; a[s].s1=a[s].s1*mu%mod,a[s].s2=a[s].s2*mu%mod*mu%mod,a[s].s3=a[s].s3*mu%mod*mu%mod*mu%mod; a[s].s3=(a[s].s3+3*ad%mod*a[s].s2%mod+3*ad%mod*ad%mod*a[s].s1%mod+c*ad%mod*ad%mod*ad%mod)%mod; a[s].s2=(a[s].s2+2*ad%mod*a[s].s1%mod+c*ad%mod*ad%mod)%mod; a[s].s1=(a[s].s1+c*ad%mod)%mod; } void phd(int x){ phd1(x,lx,a[lx].r-a[lx].l+1); phd1(x,rx,a[rx].r-a[rx].l+1); a[x].mu=1,a[x].ad=0; } void upd(int x,int l,int r,ll mu,ll ad){ if(l<=a[x].l&&r>=a[x].r){ a[0].mu=mu,a[0].ad=ad; phd1(0,x,a[x].r-a[x].l+1); return; } int mid=a[x].l+a[x].r>>1; phd(x); if(l<=mid) upd(lx,l,r,mu,ad); if(r>mid) upd(rx,l,r,mu,ad); re(x); } ll que(int x,int l,int r){ if(a[x].l>=l&&a[x].r<=r) return a[x].s3; ll ans=0,mid=a[x].l+a[x].r>>1; phd(x); if(l<=mid) ans+=que(lx,l,r); if(r>mid) ans+=que(rx,l,r); return ans%mod; } void UPD(int u,int v,ll m,ll a){ while(top[u] != top[v]){ if(dep[top[u]] < dep[top[v]]) swap(u, v); upd(1,dfn[top[u]],dfn[u], m, a); u = fa[top[u]]; } if(dep[u] < dep[v]) swap(u, v); upd(1,dfn[v],dfn[u],m,a); } ll QUE(int u, int v){ ll ans = 0; while(top[u] != top[v]){ if(dep[top[u]] < dep[top[v]]) swap(u, v); ans+=que(1,dfn[top[u]], dfn[u]); u = fa[top[u]]; } if(dep[u] < dep[v]) swap(u, v); ans += que(1, dfn[v], dfn[u]); return ans % mod; } int main(){ scanf("%d",&T);for(int k=1;k<=T;k++){ scanf("%d",&n);for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),e[u].pb(v),e[v].pb(u); for(int i=1;i<=n;i++) scanf("%d",&w[i]);scanf("%d",&Q);tim=0; dfs(1,0),dfs1(1,1); bud(1,1,n); printf("Case #%d:\n",k); while(Q--){int op,u,v,w;scanf("%d%d%d",&op,&u,&v); if(op==1) scanf("%d",&w),UPD(u,v,0,w); else if(op==2) scanf("%d",&w),UPD(u,v,1,w); else if(op==3) scanf("%d",&w),UPD(u,v,w,0); else printf("%lld\n",QUE(u,v)); }for(int i=1;i<=n;i++) e[i].clear(); } return 0; }
C++14(g++5.4) 解法, 执行用时: 10110ms, 内存消耗: 36448K, 提交时间: 2020-07-16 17:34:51
#pragma GCC optimize("Ofast,no-stack-protector") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native") #include <bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL;; #define MEM(a,b) memset((a),(b),sizeof(a)) const LL INF = 1e9 + 7; const int N = 1e5 + 10; int top[N]; int in[N]; int out[N]; int sz[N]; int depth[N]; int fa[N]; vector<int> v[N]; int cnt = 0; int a[N]; int b[N]; int dfssz(int x, int fa = 0) { ::fa[x] = fa; depth[x] = depth[fa] + 1; sz[x] = 0; int ret = 1; for (int i = 0; i < v[x].size(); i++) { int y = v[x][i]; if (y == fa) continue; ret += dfssz(y, x); } sort(v[x].begin(), v[x].end(), [](int x, int y)->bool { return sz[x] > sz[y]; }); return sz[x] = ret; } void dfshld(int x, int fa = 0) { in[x] = ++cnt; for (int i = 0; i < v[x].size(); i++) { int y = v[x][i]; if (v[x][i] == fa) continue; top[y] = (i == 0 ? top[x] : y); dfshld(y, x); } out[x] = cnt; } void query(int x, int y, vector<pair<int, int> >& vp) { while (top[x] != top[y]) { if (depth[top[x]] < depth[top[y]]) swap(x, y); vp.push_back(make_pair(in[top[x]], in[x])); x = fa[top[x]]; } if (in[x] > in[y]) swap(x, y); vp.push_back(make_pair(in[x], in[y])); } int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); ios_base::sync_with_stdio(false); cin.tie(nullptr); int ncase; cin >> ncase; int ks = 1; while (ncase--) { cout << "Case #" << ks++ << ":\n"; int n, q; cnt = 0; top[1] = 1; cin >> n; for (int i = 1; i <= n; i++) v[i].clear(); for (int i = 1; i < n; i++) { int x, y; cin >> x >> y; v[x].push_back(y); v[y].push_back(x); } for (int i = 1; i <= n; i++) { cin >> b[i]; } dfssz(1); dfshld(1); for (int i = 1; i <= n; i++) { a[in[i]] = b[i]; } cin >> q; while (q--) { int op, x, y, w; cin >> op >> x >> y; vector<pair<int, int>> vp; query(x, y, vp); if (op <= 3) cin >> w; if (op == 1) { for (auto& p : vp) { int l, r; tie(l, r) = p; for (int i = l; i <= r; i++) { a[i] = w; } } continue; } if (op == 2) { for (auto& p : vp) { int l, r; tie(l, r) = p; for (int i = l; i <= r; i++) { a[i] = (a[i] + w) % INF; } } continue; } if (op == 3) { for (auto& p : vp) { int l, r; tie(l, r) = p; for (int i = l; i <= r; i++) { a[i] = (1LL * a[i] * w) % INF; } } continue; } if (op == 4) { __int128 ans = 0; for (auto& p : vp) { int l, r; tie(l, r) = p; for (int i = l; i <= r; i++) { __int128 x = a[i]; ans += x * x * x; } } long long res = ans % INF; cout << res << '\n'; } } } return 0; }