【BZOJ2759】一个动态树好题
来源:互联网 发布:php 活动报名 源代码 编辑:程序博客网 时间:2024/05/17 06:53
Description
有N个未知数x[1..n]和N个等式组成的同余方程组:
x[i]=k[i]*x[p[i]]+b[i] mod 10007
其中,k[i],b[i],x[i]∈[0,10007)∩Z
你要应付Q个事务,每个是两种情况之一:
一.询问当前x[a]的解
A a
无解输出-1
x[a]有多解输出-2
否则输出x[a]
二.修改一个等式
C a k[a] p[a] b[a]
Input
N
下面N行,每行三个整数k[i] p[i] b[i]
Q
下面Q行,每行一个事务,格式见题目描述
Output
对每个询问,输出一行一个整数。
对100%的数据,1≤N≤30000,0≤Q≤100000,时限2秒,其中询问事务约占总数的80%
Sample Input
5
2 2 1
2 3 2
2 4 3
2 5 4
2 3 5
5
A 1
A 2
C 5 3 1 1
A 4
A 5
Sample Output
4276
7141
4256
2126
HINT
Source
By 范浩强
确实是好题,就是不会做
看了Po姐姐的题解.Po姐题解,写得很详细.
主要就是这个题不是简单地树结构,可能成环,所以要多维护一个新的父亲节点,然后扩欧+LCT.
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 30010#define P 10007#define GET (ch>='0'&&ch<='9')#define is_root(x) (tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x)using namespace std;int n,q,dfn;int vis[MAXN],p[MAXN];int sta[MAXN],top;struct data{ int k,b; friend data operator +(const data &x,const data &y) { return (data){x.k*y.k%P,(x.b*y.k+y.b)%P}; } int calc(int x) { return (k*x+b)%P; }};struct node { int x,y; };struct tree{ int ch[2],fa,fa2; data val,sum; bool rev;}tree[MAXN];inline void push_up(int x) { tree[x].sum=tree[tree[x].ch[0]].sum+tree[x].val+tree[tree[x].ch[1]].sum; }inline void push_down(int x){ if (!x) return; if (tree[x].rev) { tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1; swap(tree[x].ch[0],tree[x].ch[1]);tree[x].rev^=1; }}inline void rot(int x){ int y=tree[x].fa,z=tree[y].fa,l=(tree[y].ch[1]==x),r=l^1; if (!is_root(y)) tree[z].ch[tree[z].ch[1]==y]=x; tree[y].fa=x;tree[tree[x].ch[r]].fa=y;tree[x].fa=z; tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y; push_up(y);push_up(x);}inline void Splay(int x){ top=0;sta[++top]=x; for (int i=x;!is_root(i);i=tree[i].fa) sta[++top]=tree[i].fa; while (top) push_down(sta[top--]); while (!is_root(x)) { int y=tree[x].fa,z=tree[y].fa; if (!is_root(y)) { if ((tree[y].ch[0]==x)^(tree[z].ch[0]==y)) rot(x); else rot(y); } rot(x); }}inline void access(int x) { for (int i=0;x;i=x,x=tree[x].fa) Splay(x),tree[x].ch[1]=i,push_up(x); }inline void make_root(int x) { access(x);Splay(x);tree[x].rev^=1; }inline void link(int x,int y) { make_root(x);tree[x].fa=y; }inline void cut(int x,int y) { make_root(x);access(y);Splay(y);tree[x].fa=tree[y].ch[0]=0;push_up(y); }inline void split(int x,int y) { make_root(x);access(y);Splay(y); }inline int find_root(int x) { for (access(x),Splay(x);tree[x].ch[0];x=tree[x].ch[0]);return x; }node exgcd(int x,int y){ if (!y) return (node){1,0}; node t=exgcd(y,x%y);return (node){t.y,t.x-x/y*t.y};}inline int inv(int x) { return (exgcd((x+P)%P,P).x+P)%P; }inline int query(int x){ int root=find_root(x); access(tree[root].fa2);Splay(tree[root].fa2); int k=tree[tree[root].fa2].sum.k,b=tree[tree[root].fa2].sum.b; if (k==1) return b==0?-2:-1; int tmp=(P-b)*inv(k-1)%P; access(x);Splay(x);return tree[x].sum.calc(tmp);}inline void modify(int x,int k,int b,int f){ int root=find_root(x); tree[x].val.k=k;tree[x].val.b=b;push_up(x); if (x==root) tree[x].fa2=0; else { access(x);Splay(x); tree[tree[x].ch[0]].fa=0;tree[x].ch[0]=0; push_up(x); if (find_root(tree[root].fa2)!=root) access(root),Splay(root), tree[root].fa=tree[root].fa2,tree[root].fa2=0; } access(x);Splay(x); if (find_root(f)==x) tree[x].fa2=f; else tree[x].fa=f;}void dfs(int x){ vis[x]=dfn; if (vis[p[x]]==dfn) { tree[x].fa2=p[x];return; } tree[x].fa=p[x]; if (!vis[p[x]]) dfs(p[x]);}inline void in(int &x){ char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar();}int main(){ in(n);int x,k,f,b;char ch[3]; tree[0].val.k=tree[0].sum.k=1;tree[0].val.b=tree[0].sum.b=0; for (int i=1;i<=n;i++) in(k),in(f),in(b),p[i]=f, tree[i].val.k=k,tree[i].val.b=b, tree[i].sum.k=k,tree[i].sum.b=b; for (int i=1;i<=n;i++) if (!vis[i]) ++dfn,dfs(i); for (in(q);q;q--) { scanf("%s",ch); if (ch[0]=='A') in(x),printf("%d\n",query(x)); else in(x),in(k),in(f),in(b),modify(x,k,b,f); }}
2 0
- 【BZOJ2759】一个动态树好题
- [LCT] BZOJ2759.一个动态树好题
- bzoj2759:一个动态树好题 (LCT+Exgcd)
- bzoj2759
- 【BZOJ2759】一道动态树的好题
- bzoj2759 -- LCT
- BZOJ2759 hash
- Bzoj-2759: 一个动态树好题
- bzoj 2759 一个动态树好题 LCT 数学
- 一个动态数组类
- 动态创建一个按钮
- 动态显示一个层
- 动态创建一个组件
- 创建一个动态网页
- 自定义一个动态数组
- 动态添加一个布局
- 自定义一个动态饼状图
- BZOJ 2759 一个动态树好题 Link-Cut-Tree+扩展欧几里得
- UITableView创建
- WapApp初始化样式表
- C++继承方式
- JDBC实现文件、图片的存储实例
- 从Eclipse到Android Studio:Android项目如何进行迁移
- 【BZOJ2759】一个动态树好题
- CentOS7.1 KVM虚拟化之libguestfs-tools工具常用命令介绍(7)
- IoAttachDeviceToDeviceStack方法
- 2016第二学期Sql教学案例总目录
- CentOS7 最小安装,静态IP、网络 配置
- CList Control 控件的使用
- 本科时写的一篇《关于ISAR图像的自动目标提取技术》
- hadoop 集群开启之后datanode没有启动
- duplicate files copied in APK META_INF/NOTICE [duplicate]