bzoj 4448: [Scoi2015]情报传递
2017-09-28 17:08
357 查看
Description
奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有n名情报员。每名情报员口J-能有
若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线。奈特公司纪律森严,每
名情报员只能与自己的上、下线联系,同时,情报网络中仟意两名情报员一定能够通过情报网络传递情报。
奈特公司每天会派发以下两种任务中的一个任务:
1.搜集情报:指派T号情报员搜集情报
2.传递情报:将一条情报从X号情报员传递给Y号情报员
情报员最初处于潜伏阶段,他们是相对安全的,我们认为此时所有情报员的危险值为0;-旦某个情报员开
始搜集情报,他的危险值就会持续增加,每天增加1点危险值(开始搜集情报的当天危险值仍为0,第2天
危险值为1,第3天危险值为2,以此类推)。传递情报并不会使情报员的危险值增加。
为了保证传递情报的过程相对安全,每条情报都有一个风险控制值C。余特公司认为,参与传递这条情
报的所有情报员中,危险值大于C的情报员将对该条情报构成威胁。现在,奈特公司希望知道,对于每
个传递情报任务,参与传递的情报员有多少个,其中对该条情报构成威胁的情报员有多少个。
解题报告:
用时:1h,2WA
和上题类似,这里的风险控制值实质上是询问开始收集情报时刻小于 \(i-c\) 的节点,所以我们就以天数为下标建立主席树,然后查询路径直接用树链剖分查找即可
奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有n名情报员。每名情报员口J-能有
若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线。奈特公司纪律森严,每
名情报员只能与自己的上、下线联系,同时,情报网络中仟意两名情报员一定能够通过情报网络传递情报。
奈特公司每天会派发以下两种任务中的一个任务:
1.搜集情报:指派T号情报员搜集情报
2.传递情报:将一条情报从X号情报员传递给Y号情报员
情报员最初处于潜伏阶段,他们是相对安全的,我们认为此时所有情报员的危险值为0;-旦某个情报员开
始搜集情报,他的危险值就会持续增加,每天增加1点危险值(开始搜集情报的当天危险值仍为0,第2天
危险值为1,第3天危险值为2,以此类推)。传递情报并不会使情报员的危险值增加。
为了保证传递情报的过程相对安全,每条情报都有一个风险控制值C。余特公司认为,参与传递这条情
报的所有情报员中,危险值大于C的情报员将对该条情报构成威胁。现在,奈特公司希望知道,对于每
个传递情报任务,参与传递的情报员有多少个,其中对该条情报构成威胁的情报员有多少个。
解题报告:
用时:1h,2WA
和上题类似,这里的风险控制值实质上是询问开始收集情报时刻小于 \(i-c\) 的节点,所以我们就以天数为下标建立主席树,然后查询路径直接用树链剖分查找即可
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #define RG register #define il inline #define iter iterator #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std; const int N=200005; int head ,num=0,nxt[N<<1],to[N<<1],n,m,fa ; void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;} struct question{int x,y,c;}q ;int mt=0,tx ,root ; int dep ,top ,DFN=0,id ,sz ,son ; void dfs1(int x){ int u;sz[x]=1; for(int i=head[x];i;i=nxt[i]){ u=to[i];if(dep[u])continue; dep[u]=dep[x]+1;fa[u]=x; dfs1(u); sz[x]+=sz[u]; if(sz[u]>sz[son[x]])son[x]=u; } } void dfs2(int x,int tp){ top[x]=tp;id[x]=++DFN; if(son[x])dfs2(son[x],tp); for(int i=head[x];i;i=nxt[i]) if(to[i]!=son[x] && to[i]!=fa[x])dfs2(to[i],to[i]); } int totnode=0; struct node{int l,r,s;}t[N*80]; void updata(int &rt,int last,int l,int r,int sa){ rt=++totnode;t[rt]=t[last]; if(l==r){t[rt].s++;return ;} int mid=(l+r)>>1; if(sa>mid)updata(t[rt].r,t[last].r,mid+1,r,sa); else updata(t[rt].l,t[last].l,l,mid,sa); t[rt].s=t[t[rt].l].s+t[t[rt].r].s; } int query(int rt,int l,int r,int sa,int se){ if(l>se || r<sa)return 0; if(sa<=l && r<=se)return t[rt].s; int mid=(l+r)>>1; return query(t[rt].l,l,mid,sa,se)+query(t[rt].r,mid+1,r,sa,se); } void solve(int x,int y,int co){ int ret=0,dist=dep[x]+dep[y]; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); if(co>0)ret+=query(root[co],1,n,id[top[x]],id[x]); x=fa[top[x]]; } if(id[x]>id[y])swap(x,y); if(co>0)ret+=query(root[co],1,n,id[x],id[y]); dist-=dep[x]<<1; printf("%d %d\n",dist+1,ret); } void work() { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&fa[i]); if(fa[i])link(fa[i],i),link(i,fa[i]); } scanf("%d",&m); int flag; for(int i=1;i<=m;i++){ scanf("%d",&flag); if(flag==1){ mt++;scanf("%d%d%d",&q[mt].x,&q[mt].y,&q[mt].c); q[mt].c=i-q[mt].c-1; } else scanf("%d",&tx[i]); } dep[1]=1;dfs1(1);dfs2(1,1); for(int i=1;i<=m;i++){ if(!tx[i])root[i]=root[i-1]; else updata(root[i],root[i-1],1,n,id[tx[i]]); } for(int i=1;i<=mt;i++) solve(q[i].x,q[i].y,q[i].c); } int main() { work(); return 0; }
相关文章推荐
- 【bzoj 4448】 [Scoi2015]情报传递 离线+树剖+树状数组
- [bzoj4448] [Scoi2015]情报传递
- 【BZOJ 4448】 [Scoi2015]情报传递|树链剖分|树套树
- bzoj 4448: [Scoi2015]情报传递 (树上主席树)
- 【BZOJ4448】[Scoi2015]情报传递 主席树+LCA
- bzoj 4448: [Scoi2015]情报传递 可持久化线段树+离线
- bzoj4448 [Scoi2015]情报传递(树链剖分+主席树)
- 【bzoj4448】[Scoi2015]情报传递 主席树
- BZOJ4448 SCOI2015情报传递(离线+树链剖分+树状数组)
- bzoj 4448: [Scoi2015]情报传递
- BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树
- bzoj 4448: [Scoi2015]情报传递 dfs序列&树状数组
- bzoj4448 SCOI2015 情报传递 message
- BZOJ 4448: [Scoi2015]情报传递 树剖套主席树
- BZOJ_4448_[Scoi2015]情报传递_主席树
- bzoj4448 [Scoi2015]情报传递
- 【BZOJ 4448】 [Scoi2015]情报传递|倍增LCA|主席树
- 【bzoj4448】【SCOI2015】情报传递
- bzoj 4448: [Scoi2015]情报传递
- 【bzoj4448】SCOI2015 情报传递