BZOJ1984月下“毛景树”
2016-03-25 20:49
405 查看
1984: 月下“毛景树”
Time Limit: 20 Sec Memory Limit: 64 MB
Submit: 1298 Solved: 411
Description
毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~ “毛景树”上有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数: Change k w:将第k条树枝上毛毛果的个数改变为w个。 Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。 Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。 由于毛毛虫很贪,于是他会有如下询问: Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。
Input
第一行一个正整数N。 接下来N-1行,每行三个正整数Ui,Vi和Wi,第i+1行描述第i条树枝。表示第i条树枝连接节点Ui和节点Vi,树枝上有Wi个毛毛果。 接下来是操作和询问,以“Stop”结束。
Output
对于毛毛虫的每个询问操作,输出一个答案。
Sample Input
4
1 2 8
1 3 7
3 4 9
Max 2 4
Cover 2 4 5
Add 1 4 10
Change 1 16
Max 2 4
Stop
Sample Output
9
16
【Data Range】
1<=N<=100,000,操作+询问数目不超过100,000。
保证在任意时刻,所有树枝上毛毛果的个数都不会超过10^9个。
下狠心写这道题。。
链剖一天搞定。。
把边权下放到深度较大的点。。
WA点:
①查询操作不能用lca
②标记之间有相互作用
③修改和查询的时候要左端点右移一位
手动测试数据:
Sample Input1
9
3 5 8
3 8 9
7 8 1
5 4 7
6 7 9
3 1 3
2 1 5
9 4 6
Change 1 7
Cover 9 4 26658
Change 7 6
Max 6 4
Max 4 8
Add 5 4 868
Cover 5 2 31875
Add 2 5 26600
Change 5 1
Stop
Sample Output1
9
9
Sample Input2
5
1 3 3
1 2 1
3 4 3
5 4 3
Cover 1 5 3
Add 3 2 3
Change 4 5
Change 1 4
Max 4 1
Change 1 1
Max 5 2
Stop
Sample Output2
4
5
Sample Input3
5
3 5 1
1 5 2
1 2 2
4 5 2
Change 3 5
Cover 5 2 28916
Max 2 5
Cover 4 1 365
Max 1 5
Add 5 3 29929
Add 4 3 21700
Change 4 3
Max 4 2
Stop
Sample Output3
28916
365
28916
一个不完美的对拍:
附上本蒟蒻的代码:
Time Limit: 20 Sec Memory Limit: 64 MB
Submit: 1298 Solved: 411
Description
毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~ “毛景树”上有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数: Change k w:将第k条树枝上毛毛果的个数改变为w个。 Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。 Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。 由于毛毛虫很贪,于是他会有如下询问: Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。
Input
第一行一个正整数N。 接下来N-1行,每行三个正整数Ui,Vi和Wi,第i+1行描述第i条树枝。表示第i条树枝连接节点Ui和节点Vi,树枝上有Wi个毛毛果。 接下来是操作和询问,以“Stop”结束。
Output
对于毛毛虫的每个询问操作,输出一个答案。
Sample Input
4
1 2 8
1 3 7
3 4 9
Max 2 4
Cover 2 4 5
Add 1 4 10
Change 1 16
Max 2 4
Stop
Sample Output
9
16
【Data Range】
1<=N<=100,000,操作+询问数目不超过100,000。
保证在任意时刻,所有树枝上毛毛果的个数都不会超过10^9个。
下狠心写这道题。。
链剖一天搞定。。
把边权下放到深度较大的点。。
WA点:
①查询操作不能用lca
②标记之间有相互作用
③修改和查询的时候要左端点右移一位
手动测试数据:
Sample Input1
9
3 5 8
3 8 9
7 8 1
5 4 7
6 7 9
3 1 3
2 1 5
9 4 6
Change 1 7
Cover 9 4 26658
Change 7 6
Max 6 4
Max 4 8
Add 5 4 868
Cover 5 2 31875
Add 2 5 26600
Change 5 1
Stop
Sample Output1
9
9
Sample Input2
5
1 3 3
1 2 1
3 4 3
5 4 3
Cover 1 5 3
Add 3 2 3
Change 4 5
Change 1 4
Max 4 1
Change 1 1
Max 5 2
Stop
Sample Output2
4
5
Sample Input3
5
3 5 1
1 5 2
1 2 2
4 5 2
Change 3 5
Cover 5 2 28916
Max 2 5
Cover 4 1 365
Max 1 5
Add 5 3 29929
Add 4 3 21700
Change 4 3
Max 4 2
Stop
Sample Output3
28916
365
28916
一个不完美的对拍:
#include<cstdio> #include<ctime> #include<cstdlib> using namespace std; int main() { int i,x,y,z,n,w; srand((int)time(0)); freopen("test1.in","w",stdout); n=rand()%10; printf("%d\n",n); for (i=1;i<n;i++) { x=rand()%n+1,y=rand()%n+1,z=rand()%n+1; printf("%d %d %d\n",x,y,z); } for (i=1;i<=10;i++) { x=rand(); y=rand(),z=rand(); if (x%5==1) printf("Max %d %d\n",y%n+1,z%n+1); if (x%5==2) w=rand(),printf("Cover %d %d %d\n",y%n+1,z%n+1,w); if (x%5==3) w=rand(),printf("Add %d %d %d\n",y%n+1,z%n+1,w); if (x%5==4) printf("Change %d %d\n",y%n+1,z%n+1); } printf("Stop"); return 0; }
附上本蒟蒻的代码:
#include<cstdio> #include<iostream> #include<climits> #include<cstring> using namespace std; #define MAXN 100001 int n,cnt,sz,h[MAXN],father[MAXN][17],pos[MAXN],belong[MAXN],size[MAXN],deep[MAXN],delta1[MAXN<<2],delta2[MAXN<<2]; bool vis[MAXN]; struct data { int to,next; }edge[MAXN<<1]; struct kx { int value; }node[MAXN<<2]; struct forever { int start,end,val,point; }a[MAXN]; int read() { int w=0,c=1; char ch=getchar(); while (ch<'0' || ch>'9') { if (ch=='-') c=-1; ch=getchar(); } while (ch>='0' && ch<='9') w=w*10+ch-'0',ch=getchar(); return w*c; } void add(int u,int v) { cnt++,edge[cnt].next=h[u],h[u]=cnt,edge[cnt].to=v; cnt++,edge[cnt].next=h[v],h[v]=cnt,edge[cnt].to=u; } void dfs1(int x) { int i; size[x]=1,vis[x]=true; for (i=1;i<=16;i++) { if (deep[x]<(1<<i)) break; father[x][i]=father[father[x][i-1]][i-1]; } for (i=h[x];i;i=edge[i].next) { if (vis[edge[i].to]) continue; deep[edge[i].to]=deep[x]+1,father[edge[i].to][0]=x; dfs1(edge[i].to),size[x]+=size[edge[i].to]; } } void dfs2(int x,int chain) { int k=0,i; pos[x]=++sz,belong[x]=chain; for (i=h[x];i;i=edge[i].next) if (deep[edge[i].to]>deep[x] && size[edge[i].to]>size[k]) k=edge[i].to; if (!k) return; dfs2(k,chain); for (i=h[x];i;i=edge[i].next) if (deep[edge[i].to]>deep[x] && k!=edge[i].to) dfs2(edge[i].to,edge[i].to); } void update(int s) { node[s].value=max(node[s*2].value,node[s*2+1].value); } void build(int s,int l,int r) { if (l==r) return; build(s*2,l,(l+r)/2),build(s*2+1,(l+r)/2+1,r); } void pushdown(int s,int l,int r) { int mid=(l+r)/2; if (l==r) return; if (delta1[s]!=-1) { delta2[s*2]=delta2[s*2+1]=0,delta1[s*2]=delta1[s*2+1]=delta1[s]; node[s*2].value=node[s*2+1].value=delta1[s],delta1[s]=-1; } if (delta2[s]) { node[s*2].value+=delta2[s],node[s*2+1].value+=delta2[s]; if (delta1[s*2]!=-1) delta1[s*2]+=delta2[s]; else delta2[s*2]+=delta2[s]; if (delta1[s*2+1]!=-1) delta1[s*2+1]+=delta2[s]; else delta2[s*2+1]+=delta2[s]; delta2[s]=0; } } void change(int s,int l,int r,int x,int y) { pushdown(s,l,r); int mid=(l+r)/2; if (l==x && l==r) { node[s].value=y; return; } if (x<=mid) change(s*2,l,mid,x,y); else change(s*2+1,mid+1,r,x,y); update(s); } int querymax(int s,int l,int r,int x,int y) { int mid=(l+r)/2,ans; pushdown(s,l,r); if (x>y) return -INT_MAX; if (x<=l && y>=r) return node[s].value; if (x<=mid) ans=querymax(s*2,l,mid,x,y); else ans=-INT_MAX; if (y>mid) ans=max(ans,querymax(s*2+1,mid+1,r,x,y)); update(s); return ans; } int solvemax(int x,int y) { int mx=-INT_MAX; for (;belong[x]!=belong[y];x=father[belong[x]][0]) { if (deep[belong[x]]<deep[belong[y]]) swap(x,y); mx=max(mx,querymax(1,1,n,pos[belong[x]],pos[x])); } if (deep[x]<deep[y]) swap(x,y); mx=max(mx,querymax(1,1,n,pos[y]+1,pos[x])); return mx; } void insert1(int s,int l,int r,int x,int y,int z) { pushdown(s,l,r); int mid=(l+r)/2; if (x<=l && y>=r) { node[s].value=delta1[s]=z; return; } if (x<=mid) insert1(s*2,l,mid,x,y,z); if (y>mid) insert1(s*2+1,mid+1,r,x,y,z); update(s); } void solveinsert1(int x,int y,int z) { for (;belong[x]!=belong[y];x=father[belong[x]][0]) { if (deep[belong[x]]<deep[belong[y]]) swap(x,y); insert1(1,1,n,pos[belong[x]],pos[x],z); } if (deep[x]<deep[y]) swap(x,y); insert1(1,1,n,pos[y]+1,pos[x],z); } void insert2(int s,int l,int r,int x,int y,int z) { pushdown(s,l,r); int mid=(l+r)/2; if (x<=l && y>=r) { node[s].value+=z,delta2[s]=z; return; } if (x<=mid) insert2(s*2,l,mid,x,y,z); if (y>mid) insert2(s*2+1,mid+1,r,x,y,z); update(s); } void solveinsert2(int x,int y,int z) { for (;belong[x]!=belong[y];x=father[belong[x]][0]) { if (deep[belong[x]]<deep[belong[y]]) swap(x,y); insert2(1,1,n,pos[belong[x]],pos[x],z); } if (deep[x]<deep[y]) swap(x,y); insert2(1,1,n,pos[y]+1,pos[x],z); } int main() { /*freopen("test1.in","r",stdin); freopen("test1.out","w",stdout);*/ memset(delta1,-1,sizeof(delta1)); int i,x,y,z,t; char s[10]; n=read(); for (i=1;i<n;i++) a[i].start=read(),a[i].end=read(),a[i].val=read(),add(a[i].start,a[i].end); dfs1(1),dfs2(1,1),build(1,1,n); /*for (i=1;i<=n;i++) printf("%d ",deep[i]); printf("\n");*/ for (i=1;i<n;i++) if (deep[a[i].start]>deep[a[i].end]) a[i].point=a[i].start; else a[i].point=a[i].end; for (i=1;i<n;i++) change(1,1,n,pos[a[i].point],a[i].val); while (scanf("%s",&s)) { if (s[1]=='t') break; x=read(),y=read(); if (s[1]=='a') printf("%d\n",solvemax(x,y)); if (s[1]=='o') z=read(),solveinsert1(x,y,z); if (s[1]=='d') z=read(),solveinsert2(x,y,z); if (s[1]=='h') change(1,1,n,pos[a[x].point],y); } return 0; }
相关文章推荐
- HDU 4081 Qin Shi Huang's National Road System (次小生成树算法)
- C++中头文件(.h)和源文件(.cpp)都应该写些什么
- Spark机器学习5·回归模型(pyspark)
- 在windows上部署使用Redis
- ListView in fragment 列表视图的使用
- IOS删除沙盒所有同类型的文件
- Spark机器学习4·分类模型(spark-shell)
- Spark机器学习3·推荐引擎(spark-shell)
- Android课程---布局管理器之相对布局(一)
- datagrid页面获取表单一条数据的例子
- IOC(控制反转,反向控制)
- Spark机器学习2·准备数据(pyspark)
- 【GDOI2016模拟7.10】Banner
- uoj171 bzoj4405 挑战NPC 一般图最大匹配
- JavaScript 操作页面元素
- Spark机器学习1·编程入门(scala/java/python)
- test
- 各种开发环境代码对齐方式
- hdu 3172(并查集+hash)
- Circumventing Group Policy Settings