博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WC2013 糖果公园
阅读量:7260 次
发布时间:2019-06-29

本文共 5831 字,大约阅读时间需要 19 分钟。

COGS 1817. [WC2013]糖果公园

★★★☆   输入文件:park.in   输出文件:park.out   简单对比
时间限制:8 s   内存限制:512 MB

【题目描述】

 

    Candyland 有一座糖果公园,公园里不仅有美丽的风景、好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园玩。

    糖果公园的结构十分奇特,它由 n 个游览点构成,每个游览点都有一个糖果发放处,我们可以依次将游览点编号为 1 至 n。有 n−1 条双向道路连接着这些游览点,并且整个糖果公园都是连通的,即从任何一个游览点出发都可以通过这些道路到达公园里的所有其它游览点。

    糖果公园所发放的糖果种类非常丰富,总共 m 种,它们的编号依次为 1 至 m。每一个糖果发放处都只发放某种特定的糖果,我们用 ci 来表示 i 号游览点的糖果。

    来到公园里游玩的游客都不喜欢走回头路,他们总是从某个特定的游览点出发前往另一个特定的游览点,并游览途中的景点,这条路线一定是唯一的。他们经过每个游览点,都可以品尝到一颗对应种类的糖果。

    大家对不同类型的糖果的喜爱程度都不尽相同。根据游客们的反馈打分,我们得到了糖果的美味指数,第 i 种糖果的美味指数为 vi。另外,如果一位游客反复地品尝同一种类的糖果,他肯定会觉得有一些腻。根据量化统计,我们得到了游客第 i 次品尝某类糖果的新奇指数 wi,如果一位游客第 i 次品尝第 j 种糖果,那么他的愉悦指数 H 将会增加对应的美味指数与新奇指数的乘积,即 vjwi。这位游客游览公园的愉悦指数最终将是这些乘积的和。

    当然,公园中每个糖果发放点所发放的糖果种类不一定是一成不变的。有时,一些糖果点所发放的糖果种类可能会更改(也只会是 m 种中的一种),这样的目的是能够让游客们总是感受到惊喜。

    糖果公园的工作人员小 A 接到了一个任务,那就是根据公园最近的数据统计出每位游客游玩公园的愉悦指数。但数学不好的小 A 一看到密密麻麻的数字就觉得头晕,作为小 A 最好的朋友,你决定帮他一把。

 

【输入格式

 

    第一行包含三个正整数 n,m,q,分别表示游览点个数、糖果种类数和操作次数。

    第二行包含 m 个正整数 v1,v2,…,vm。

    第三行包含 n 个正整数 w1,w2,…,wn。

    第四行到第 n+2 行,每行包含两个正整数 ai,bi,表示这两个游览点之间有路径可以直接到达。

    第 n+3 行包含 n 个正整数 c1,c2,…,cn。

    接下来 q 行,每行包含三个整数 t,x,y,表示一次操作:

    若 t 为 0,则 1≤x≤n,1≤y≤m,表示编号为 x 的游览点发放的糖果类型改为 y;

    若 t 为 1,则 1≤x,y≤n,表示对出发点为 x,终止点为 y 的路线询问愉悦指数。

 

【输出格式

 

    按照输入的先后顺序,对于每个 t 为 1 的操作输出一行,用一个正整数表示答案。

 

【样例输入】

4 3 51 9 27 6 5 12 33 13 41 2 3 21 1 21 4 20 2 11 1 21 4 2

【样例输出】

841312784

【数据范围】

 

树上带修改莫队

dfs序分块:

 

#include
#include
#include
#define N 100001using namespace std;int n,m,q,siz;int tasty[N],curious[N],type[N];int front[N],to[N<<1],nxt[N<<1],tot;int now,cnt,block[N],sum[N];int son[N],deep[N],dfn[N],bl[N],fa[N];long long tmp,ans[N];bool v[N];struct QUERY{ int l,r,id,tim; bool operator < (QUERY p)const { if(block[l]!=block[p.l]) return block[l]
'9') c=getchar(); while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); }}void out(long long x){ if(x/10) out(x/10); putchar(x%10+'0');}void add(int u,int v){ to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;}void init(){ read(n); read(m); read(q); siz=sqrt(n); for(int i=1;i<=m;i++) read(tasty[i]); for(int i=1;i<=n;i++) read(curious[i]); int u,v; for(int i=1;i
son[y]) y=to[i]; } if(!y) return; dfs2(y,top); for(int i=front[x];i;i=nxt[i]) { if(to[i]==fa[x]||to[i]==y) continue; dfs2(to[i],to[i]); }}int get_lca(int u,int v){ while(bl[u]!=bl[v]) { if(deep[bl[u]]
deep[v]) swap(u,v); return u;}void point(int x){ if(v[x]) { long long o=curious[sum[type[x]]--]; tmp-=1ll*tasty[type[x]]*o; } else { long long o=curious[++sum[type[x]]]; tmp+=1ll*tasty[type[x]]*o; } v[x]^=1;}void path(int u,int v){ while(u!=v) { if(deep[u]
e[i].tim) { if(v[g[now].pos]) { point(g[now].pos); type[g[now].pos]=g[now].be; point(g[now].pos); } else type[g[now].pos]=g[now].be; now--; } if(dfn[e[i].l]>dfn[e[i].r]) swap(e[i].l,e[i].r); path(L,e[i].l); path(R,e[i].r); lca=get_lca(e[i].l,e[i].r); point(lca); ans[e[i].id]=tmp; point(lca); L=e[i].l; R=e[i].r; //printf("%d %d:",e[i].l,e[i].r); //printf("%I64d\n",tmp); } for(int i=1;i<=cnt;i++) out(ans[i]),puts("");}int main(){ init(); dfs1(1); dfs2(1,1); sort(e+1,e+cnt+1); solve();}
View Code

 

树上分块:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 1000000000#define ll long longusing namespace std;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}ll ans,res[100005];int bin[20];int n,m,Q,ind,cnt,top;int blo,blonum;ll V[100005],W[100005],C[100005],pre[100005];int fa[100005][17];int last[100005],q[100005],deep[100005],belong[100005],dfn[100005];int num[100005];bool vis[100005];struct edge{ int to,next;}e[200005];struct query{ int x,y,t,id;}b[100005];struct change{ int x,y,t,pre;}c[100005];bool operator<(query a,query b){ if(belong[a.x]==belong[b.x]&&belong[a.y]==belong[b.y])return a.t
=bin[i]) fa[x][i]=fa[fa[x][i-1]][i-1]; else break; for(int i=last[x];i;i=e[i].next) if(e[i].to!=fa[x][0]) { deep[e[i].to]=deep[x]+1; fa[e[i].to][0]=x; size+=dfs(e[i].to); if(size>=blo) { blonum++; for(int k=1;k<=size;k++) belong[q[top--]]=blonum; size=0; } } q[++top]=x; return size+1;}int lca(int x,int y){ if(deep[x]
=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; if(x==y)return x; return fa[x][0];}void reverse(int x){ if(vis[x])ans-=W[num[C[x]]]*V[C[x]],num[C[x]]--; else num[C[x]]++,ans+=W[num[C[x]]]*V[C[x]]; vis[x]^=1;}void change(int x,int y){ if(vis[x]) { reverse(x); C[x]=y; reverse(x); } else C[x]=y;}void solve(int x,int y){ while(x!=y) { if(deep[x]>deep[y])reverse(x),x=fa[x][0]; else reverse(y),y=fa[y][0]; }}int main(){ bin[0]=1; for(int i=1;i<20;i++)bin[i]=bin[i-1]<<1; n=read();m=read();Q=read(); blo=pow(n,2.0/3)*0.5; for(int i=1;i<=m;i++)V[i]=read(); for(int i=1;i<=n;i++)W[i]=read(); for(int i=1;i
dfn[y])swap(x,y); b[c2].x=x;b[c2].y=y;b[c2].id=c2;b[c2].t=c1; } } sort(b+1,b+c2+1); for(int i=1;i<=b[1].t;i++) change(c[i].x,c[i].y); solve(b[1].x,b[1].y); int t=lca(b[1].x,b[1].y); reverse(t);res[b[1].id]=ans;reverse(t); for(int i=2;i<=c2;i++) { for(int j=b[i-1].t+1;j<=b[i].t;j++) change(c[j].x,c[j].y); for(int j=b[i-1].t;j>b[i].t;j--) change(c[j].x,c[j].pre); solve(b[i-1].x,b[i].x); solve(b[i-1].y,b[i].y); int t=lca(b[i].x,b[i].y); reverse(t);res[b[i].id]=ans;reverse(t); } for(int i=1;i<=c2;i++) printf("%lld\n",res[i]); return 0;}
View Code

 

 

 

 

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/7072367.html

你可能感兴趣的文章
LINUX下安装软件方法命令方法
查看>>
关于CoInitialize和CoUninitialize调用的有关问题
查看>>
公有属性和私有属性
查看>>
android adb 源码框架分析(1 系统)【转】
查看>>
Day4 MySql触发器视图索引以及设计优化
查看>>
Oracle内存管理(之四)
查看>>
js bind 绑定this指向
查看>>
Apache Shiro 使用手册(二)Shiro 认证
查看>>
SQL Server修改标识列方法(备忘)
查看>>
Spring中Mybatis的花样配置 及 原理
查看>>
malloc原理和内存碎片【转】
查看>>
文档的js
查看>>
React Props
查看>>
ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台
查看>>
Android接口和框架学习
查看>>
获取表单select域的选择部分的文本
查看>>
Linux 下socket通信终极指南(附TCP、UDP完整代码)
查看>>
Python常用模块-摘要算法(hashlib)
查看>>
小程序flex属性两边边距自适应
查看>>
缓存更新的套路
查看>>