博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jzoj5984. 【北大2019冬令营模拟2019.1.1】仙人掌 (分块)
阅读量:7114 次
发布时间:2019-06-28

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

题面

5c30321096069.png

题解

数据结构做傻了.jpg

考虑每一个节点,它的儿子的取值最多只有\(O(\sqrt {m})\)种,那么可以用一个双向链表维护儿子的所有取值以及该取值的个数,那么对儿子节点修改一个值就是\(O(\sqrt{m})\),整体修改可以通过在自己身上打一个标记做到\(O(1)\)

然后还要修改父亲,那么可以通过修改父亲的父亲的儿子实现,并把父亲打上一个加一标记

然后还需要知道该时刻某个点的具体取值,可以通过父亲身上整体加一的标记和自己身上被儿子打的标记的总和求出

//minamoto#include
#define R register#define fp(i,a,b) for(R int i=a,I=b+1;i
I;--i)#define go(G,u) for(int i=G.head[u],v=G.e[i].v;i;i=G.e[i].nx,v=G.e[i].v)using namespace std;char buf[1<<21],*p1=buf,*p2=buf;inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}int read(){ R int res,f=1;R char ch; while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1); for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0'); return res*f;}char sr[1<<21],z[20];int C=-1,Z=0;inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}void print(R int x){ if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x; while(z[++Z]=x%10+48,x/=10); while(sr[++C]=z[Z],--Z);sr[++C]='\n';}const int N=5e5+5,P=1000109107;inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}int ksm(R int x,R int y){ R int res=1; for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x); return res;}struct Gr{ struct eg{int v,nx,w;}e[N<<1];int head[N],tot; inline void add(R int u,R int v){e[++tot]={v,head[u],1},head[u]=tot;} inline void init(int u,int v){e[++tot].w=v,head[u]=tot;}}G,T;int t1[N],t2[N],son[N],fa[N];int n,m,res,sum,u,v;void dfs(int u){ go(G,u)if(v!=fa[u]){ fa[v]=u,dfs(v); ++son[u]; }}int main(){// freopen("testdata.in","r",stdin); freopen("cactus.in","r",stdin); freopen("cactus.out","w",stdout); n=read(),m=read(); fp(i,1,n-1)u=read(),v=read(),G.add(u,v),G.add(v,u); dfs(1);fa[1]=n+1,son[n+1]=1; fp(i,1,n+1)if(son[i])T.init(i,son[i]); fp(j,1,m){ u=read(),sum=0; go(T,u)++T.e[i].v; if(u>1){ int ff=fa[fa[u]],val=t2[fa[u]]+t1[ff],las=0; go(T,ff)if(T.e[i].v==val){ if(T.e[i].w>1)--T.e[i].w; else{ if(i==T.head[ff])T.head[ff]=T.e[i].nx; else T.e[las].nx=T.e[i].nx; }break; }else las=i; ++val;int flag=0; go(T,ff)if(T.e[i].v==val){++T.e[i].w,flag=1;break;} if(!flag)T.add(ff,val); sum=val; }++t1[u],++t2[fa[u]]; go(T,u)if(T.e[i].w&1)sum^=T.e[i].v;// printf("%d\n",sum); res=add(res,mul(sum,add(mul(j,j),j))); }printf("%d\n",res); return 0;}

转载于:https://www.cnblogs.com/bztMinamoto/p/10224016.html

你可能感兴趣的文章
为什么ES6新增了Promise对象来处理异步调用
查看>>
珍惜每一个假期
查看>>
解决循环引用
查看>>
使用harbor和nexus作为docker registry
查看>>
rdc第四天
查看>>
关于 Android studio 在xml中不提示的问题
查看>>
Spring系列之AOP分析开篇(一)
查看>>
关于Android中多module使用fat-aar合并的坑
查看>>
同时兼容iOS、Android、微信小程序的UI引擎
查看>>
KVC的取值赋值
查看>>
Vue2.x+axios+iview+mui带你撸一个App
查看>>
首屏预渲染方案
查看>>
漫谈直播:从零开始认识直播并快速搭建专属直播平台
查看>>
vue学习第一天 - 安装
查看>>
Vue源码分析系列三:render
查看>>
2018上半年信息系统项目管理师真题
查看>>
为 Charles 添加代理页面按钮(Rewrite)
查看>>
决战燕京城-03 公司倒闭风波
查看>>
python面向对象[基础]
查看>>
如何使用榛子获得第一条短信验证码?
查看>>