首页 > 其他 > 详细

2019ICPC 上海现场赛补题

时间:2020-05-09 00:37:03      阅读:91      评论:0      收藏:0      [点我收藏+]

F - A Simple Problem On A Tree

题目:传送门

贼恶心的一个大树剖,写了两遍才过。为了简化代码,写了很多函数;操作1 区间赋值w 可以直接写,但也可以转化成 乘以0 再加上w。

其中需要注意,立方和、平方和、一次幂和的更新顺序;还有延时标记的初始化

技术分享图片
  1 #include<bits/stdc++.h>
  2 /*
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<vector>
  7 #include<cctype>
  8 #include<queue>
  9 #include<algorithm>
 10 #include<map>
 11 #include<set>
 12 */
 13 #pragma GCC optimize(2)
 14 using namespace std;
 15 typedef long long LL;
 16 typedef pair<int,int> pii;
 17 typedef pair<double,double> pdd;
 18 const int N=2e5+5;
 19 const int M=3005;
 20 const int inf=0x3f3f3f3f;
 21 const LL mod=1e9+7;
 22 const double eps=1e-9;
 23 const long double pi=acos(-1.0L);
 24 #define ls (i<<1)
 25 #define rs (i<<1|1)
 26 #define fi first
 27 #define se second
 28 #define pb push_back
 29 #define mk make_pair
 30 #define mem(a,b) memset(a,b,sizeof(a))
 31 LL read()
 32 {
 33     LL x=0,t=1;
 34     char ch;
 35     while(!isdigit(ch=getchar())) if(ch==-) t=-1;
 36     while(isdigit(ch)){ x=10*x+ch-0; ch=getchar(); }
 37     return x*t;
 38 }
 39 LL lazy1[N<<2],lazy2[N<<2];
 40 int deep[N],id[N],top[N],f[N],cnt[N],son[N],tot,n,m,a[N],rk[N];
 41 vector<int> e[N];
 42 struct node{ LL x,y,z; }c[N<<2];
 43 void dfs(int u,int pre)
 44 {
 45     f[u]=pre;
 46     cnt[u]=1;
 47     deep[u]=deep[pre]+1;
 48     for(auto v:e[u])
 49     {
 50         if(v==pre) continue;
 51         dfs(v,u);
 52         cnt[u]+=cnt[v];
 53         if(cnt[son[u]]<cnt[v]) son[u]=v;
 54     }
 55 }
 56 void dfs2(int u,int pre,int t)
 57 {
 58     top[u]=t;
 59     id[u]=++tot;
 60     rk[tot]=u;
 61     if(son[u]) dfs2(son[u],u,t);
 62     for(auto v:e[u])
 63         if(v!=son[u]&&v!=pre) dfs2(v,u,v);
 64 }
 65 inline LL s2(LL x)
 66 {
 67     return x*x%mod;
 68 }
 69 inline LL s3(LL x)
 70 {
 71     return x*x%mod*x%mod;
 72 }
 73 void calmul(int i,LL w)
 74 {
 75     c[i].x=c[i].x*w%mod;
 76     c[i].y=c[i].y*s2(w)%mod;
 77     c[i].z=c[i].z*s3(w)%mod;
 78     lazy1[i]=lazy1[i]*w%mod;
 79     lazy2[i]=lazy2[i]*w%mod;
 80 }
 81 void caladd(int i,LL len,LL w)
 82 {
 83     c[i].z=(c[i].z+len*s3(w)%mod+3LL*s2(w)%mod*c[i].x+3LL*w%mod*c[i].y%mod )%mod;
 84     c[i].y=(c[i].y+len*s2(w)%mod+2LL*w%mod*c[i].x%mod )%mod;
 85     c[i].x=(c[i].x+len*w%mod )%mod;
 86     lazy2[i]=(lazy2[i]+w)%mod;
 87 }
 88 void pushup(int i)
 89 {
 90     c[i].x=(c[ls].x+c[rs].x)%mod;
 91     c[i].y=(c[ls].y+c[rs].y)%mod;
 92     c[i].z=(c[ls].z+c[rs].z)%mod;
 93 }
 94 void pushdown(int i,int l,int r)
 95 {
 96     int mid=l+r>>1;
 97     calmul(ls,lazy1[i]);
 98     calmul(rs,lazy1[i]);
 99     caladd(ls,mid-l+1,lazy2[i]);
100     caladd(rs,r-mid,lazy2[i]);
101     lazy1[i]=1;
102     lazy2[i]=0;
103 }
104 void build(int i,int l,int r)
105 {
106     lazy1[i]=1;
107     lazy2[i]=0;
108     if(l==r)
109     {
110         LL t=a[rk[l]];
111         c[i].x=t;
112         c[i].y=s2(t);
113         c[i].z=s3(t);
114         return ;
115     }
116     int mid=l+r>>1;
117     build(ls,l,mid);
118     build(rs,mid+1,r);
119     pushup(i);
120 }
121 void update(int i,int l,int r,int ll,int rr,int flag,LL w)
122 {
123     if(ll<=l&&r<=rr)
124     {
125         if(flag==1)
126         {
127             LL len=r-l+1;
128             lazy1[i]=0;
129             lazy2[i]=w;
130             c[i].x=w*len%mod;
131             c[i].y=s2(w)*len%mod;
132             c[i].z=s3(w)*len%mod;
133         }
134         else if(flag==2) caladd(i,r-l+1,w);
135         else calmul(i,w);
136         return ;
137     }
138     pushdown(i,l,r);
139     int mid=l+r>>1;
140     if(mid>=ll) update(ls,l,mid,ll,rr,flag,w);
141     if(mid<rr) update(rs,mid+1,r,ll,rr,flag,w);
142     pushup(i);
143 }
144 LL query(int i,int l,int r,int ll,int rr)
145 {
146     if(ll<=l&&r<=rr) return c[i].z;
147     pushdown(i,l,r);
148     LL t1=0,t2=0;
149     int mid=l+r>>1;
150     if(mid>=ll) t1=query(ls,l,mid,ll,rr);
151     if(mid<rr) t2=query(rs,mid+1,r,ll,rr);
152     return (t1+t2)%mod;
153 }
154 void change(int x,int y,int flag,LL w)
155 {
156     while(top[x]!=top[y])
157     {
158         if(deep[top[x]]<deep[top[y]]) swap(x,y);
159         update(1,1,n,id[top[x]],id[x],flag,w);
160         x=f[top[x]];
161     }
162     if(id[x]>id[y]) swap(x,y);
163     update(1,1,n,id[x],id[y],flag,w);
164 }
165 LL getans(int x,int y)
166 {
167     LL ans=0;
168     while(top[x]!=top[y])
169     {
170         if(deep[top[x]]<deep[top[y]]) swap(x,y);
171         ans+=query(1,1,n,id[top[x]],id[x]);
172         ans%=mod;
173         x=f[top[x]];
174     }
175     if(id[x]>id[y]) swap(x,y);
176     ans+=query(1,1,n,id[x],id[y]);
177     ans%=mod;
178     return ans;
179 }
180 inline void init()
181 {
182     tot=0;
183     mem(son,0);
184     for(int i=1;i<=n;i++) e[i].clear();
185 }
186 int main()
187 {
188     int T=read(),test=0;
189     while(T--)
190     {
191         n=read();
192         for(int i=1;i<n;i++)
193         {
194             int x=read(),y=read();
195             e[x].pb(y);
196             e[y].pb(x);
197         }
198         for(int i=1;i<=n;i++) a[i]=read();
199         dfs(1,0);
200         dfs2(1,0,1);
201         build(1,1,n);
202         m=read();
203         printf("Case #%d:\n",++test);
204         while(m--)
205         {
206             int cmd=read(),u=read(),v=read();
207             if(cmd==4) printf("%lld\n",getans(u,v));
208             else
209             {
210                 LL w=read();
211                 change(u,v,cmd,w);
212             }
213         }
214         init();
215     }
216     return 0;
217 }
View Code

 

2019ICPC 上海现场赛补题

原文:https://www.cnblogs.com/DeepJay/p/12853653.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!