[2017集训队作业自选题#154]简单数据结构题
来源:互联网 发布:杭州工商大学网络教育 编辑:程序博客网 时间:2024/06/03 13:25
题目大意
一颗点权树,初始点权均为0。
每次操作将所有距离x为1的点点权+1,然后希望你求出距离x为1的点点权异或和。
一个转化
把修改分成儿子修改和单点修改,把询问分成儿子询问和单点询问。
每次相当于x的儿子修改+x的父亲单点修改,询问类似。
根号算法
发现一个点儿子的点权种类数最多根号种。
不妨用链表(动态桶)维护每种点权出现次数。
正解
注意到x^(x+1)=2*lowbit(~x)-1。
我们不妨对一个点的儿子的点权维护一颗trie(从低位到高位)。
每次执行儿子修改时,0边出去的都是lowbit(~x)在这一位的,然后+1后会变成1,而1边+1后变成0,且还要继续进位,因此交换01儿子,继续递归0儿子。
#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef long long ll;const int maxn=500000+10,maxtot=maxn*40,mo=1000000007,maxd=19;int h[maxn],go[maxn*2],nxt[maxn*2],fa[maxn],v[maxn],a[maxn];int root[maxn],ans[maxn],tree[maxtot][2],size[maxtot];int i,j,k,l,t,n,m,tot,wdc,num;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;}void add(int x,int y){ go[++tot]=y; nxt[tot]=h[x]; h[x]=tot;}void dfs(int x,int y){ fa[x]=y; int t=h[x]; while (t){ if (go[t]!=y) dfs(go[t],x); t=nxt[t]; }}void insert(int &x,int d,int v,int f){ if (!x) x=++tot; size[x]+=f; if (d==maxd) return; insert(tree[x][v%2],d+1,v/2,f);}void change(int x,int d){ if (!x||d==maxd) return; int t=(1<<(d+1))-1; if (size[tree[x][0]]%2==1) wdc^=t; swap(tree[x][0],tree[x][1]); change(tree[x][0],d+1);}void modify(int x){ int y=a[x]; if (fa[x]) y+=v[fa[x]]; wdc=y+1; if (fa[x]){ insert(root[fa[x]],0,y,-1); insert(root[fa[x]],0,y+1,1); ans[fa[x]]^=y^(y+1); } a[x]++;}void write(int ans){ int t=((ll)i*i%mo+i)%mo; t=(ll)t*ans%mo; (num+=t)%=mo; //printf("%d\n",ans);}int main(){ //freopen("ans.out","w",stdout); n=read();m=read(); fo(i,1,n-1){ j=read();k=read(); add(j,k);add(k,j); } dfs(1,0); tot=0; fo(i,1,n) if (fa[i]) insert(root[fa[i]],0,0,1); fo(i,1,m){ j=read(); wdc=0; change(root[j],0); ans[j]^=wdc; wdc=0; if (fa[j]) modify(fa[j]); v[j]++; write(ans[j]^wdc); } (num+=mo)%=mo; printf("%d\n",num);}
阅读全文
0 0
- [2017集训队作业自选题#154]简单数据结构题
- [2017集训队作业自选题#153]Comb Avoiding Trees
- [2017集训队作业自选题#117]Monkey and Tree
- [2017集训队作业自选题#115]Replace All
- [2017集训队作业自选题#119]众数MAX
- [2017集训队作业自选题#134]Counting Divisors (square)
- [2017集训队作业自选题#148]Simple Summation Problem
- [2017集训队作业自选题#107]An unavoidable detour for home
- 集训队作业
- 我的集训队作业
- 【集训队作业】MONOPLOY
- 【集训队作业】TREECNT2
- 【集训队作业】DGCD
- 【集训队作业】XRQRS
- 【集训队作业】LYRC
- 【集训队作业】COUNTARI
- 2015年集训队作业
- 【AtCoder arc072_f/集训队作业】 Dam
- React Hello JSX
- springboot jpa
- VS 各种工程文件说明
- android基础-build target,minSdkVersion,targetSdkVersion,maxSdkVersion概念区分
- 关于curl和json的安装和使用
- [2017集训队作业自选题#154]简单数据结构题
- 【递归入门】全排列
- Nginx的connect() failed 错误解决
- 经验分享:thinkphp 5是如何实现验证码功能的
- 关于json的理解(js中)
- Linux下Notepad++的替代品
- 输出最大值
- Android Dex文件格式解析
- 编译失败,但没有错误提示