2631: tree

来源:互联网 发布:大数据分析师招聘 编辑:程序博客网 时间:2024/05/22 14:31

2631: tree

Time Limit: 30 Sec  Memory Limit: 128 MB
Submit: 3561  Solved: 1189
[Submit][Status][Discuss]

Description

 一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
+ u v c:将u到v的路径上的点的权值都加上自然数c;
- u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
* u v c:将u到v的路径上的点的权值都乘上自然数c;
/ u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。

Input

  第一行两个整数n,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作

Output

  对于每个/对应的答案输出一行

Sample Input

3 2
1 2
2 3
* 1 3 4
/ 1 1

Sample Output

4


HINT

数据规模和约定

10%的数据保证,1<=n,q<=2000

另外15%的数据保证,1<=n,q<=5*10^4,没有-操作,并且初始树为一条链

另外35%的数据保证,1<=n,q<=5*10^4,没有-操作

100%的数据保证,1<=n,q<=10^5,0<=c<=10^4


Source

[Submit][Status][Discuss]

一看就是LCT?
标记的转移记得用矩阵乘法,,自己先推一下
(WA惨了)
然后这题丧心病狂卡常数啊。。。
maintain可以少打一些(如rotate操作只需要一个maintain)
最后,,本题请使用unsigned int
long long计算更慢些(日。。。)
#include<iostream>#include<cstdio>#include<queue>#include<vector>#include<bitset>#include<algorithm>#include<cstring>#include<map>#include<stack>#include<set>#include<cmath>#include<ext/pb_ds/priority_queue.hpp>using namespace std;const int maxn = 1E5 + 10;typedef unsigned int LL;const LL mo = 51061;int n,m,ch[maxn][2],rev[maxn],fa[maxn],pfa[maxn],vis[maxn];LL va[maxn],sum[maxn],Add[maxn],siz[maxn],Multi[maxn];char com[10];vector <int> v[maxn];queue <int> Q;void pushdown(int x){if (rev[x]) {swap(ch[x][0],ch[x][1]); rev[x] ^= 1;if (ch[x][0]) rev[ch[x][0]] ^= 1;if (ch[x][1]) rev[ch[x][1]] ^= 1;}if (Add[x] || Multi[x] != 1) {va[x] *= Multi[x]; va[x] %= mo;sum[x] *= Multi[x]; sum[x] %= mo;va[x] += Add[x]; va[x] %= mo;sum[x] += Add[x]*siz[x]; sum[x] %= mo;for (int i = 0; i < 2; i++)if (ch[x][i]) {Add[ch[x][i]] = Multi[x]*Add[ch[x][i]] + Add[x],Add[ch[x][i]] %= mo;Multi[ch[x][i]] *= Multi[x],Multi[ch[x][i]] %= mo;}Add[x] = 0; Multi[x] = 1;}}void maintain(int x){siz[x] = 1; sum[x] = va[x];for (int i = 0; i < 2; i++)if (ch[x][i]) {siz[x] += siz[ch[x][i]];sum[x] += sum[ch[x][i]]; sum[x] %= mo;}}void rotate(int x){int y = fa[x],z = fa[y];pfa[x] = pfa[y]; pfa[y] = 0;int d = ch[y][0] == x?0:1;ch[y][d] = ch[x][d^1];if (ch[x][d^1]) fa[ch[x][d^1]] = y; ch[x][d^1] = y; fa[y] = x; fa[x] = z;if (z) ch[z][ch[z][1] == y] = x;if (ch[y][0]) pushdown(ch[y][0]);if (ch[y][1]) pushdown(ch[y][1]);maintain(y);}int s[maxn],top;void splay(int x){top = 0;for (int now = x; now; now = fa[now]) s[++top] = now;while (top) {pushdown(s[top--]);}for (int y; y = fa[x]; rotate(x))if (fa[y])rotate((ch[fa[y]][0] == y)^(ch[y][0] == x)?x:y);if (ch[x][0]) pushdown(ch[x][0]);if (ch[x][1]) pushdown(ch[x][1]);maintain(x);}void Access(int x){for (int u = x,v = 0; u; v = u,u = pfa[u]) {splay(u);if (ch[u][1]) fa[ch[u][1]] = 0,pfa[ch[u][1]] = u;ch[u][1] = v; if (v) pfa[v] = 0,fa[v] = u;}}void ChangeRoot(int x) {Access(x); splay(x); rev[x] ^= 1;}void Join(int x,int y) {ChangeRoot(x); pfa[x] = y; splay(y);}void Cut(int x,int y) {ChangeRoot(x); Access(y); splay(y); ch[y][0] = fa[x] = 0;}int Query(int x,int y) {ChangeRoot(x); Access(y); splay(y); return sum[y];}void add(int x,int y,int c){ChangeRoot(x); Access(y); splay(y);Add[y] += 1LL*c; Add[y] %= mo; }void multi(int x,int y,int c){ChangeRoot(x); Access(y); splay(y);//Add[y] *= 1LL*c; Add[y] %= mo;Multi[y] *= 1LL*c; Multi[y] %= mo; }int getint(){char ch = getchar();int ret = 0;while (ch < '0' ||  '9' < ch) ch = getchar();while ('0' <= ch && ch <= '9') ret = ret*10 + ch - '0',ch = getchar();return ret;}char c[20];void print( int k )    {    if (!k) {puts("0"); return;}    int num = 0;        while( k > 0 ) c[++num] = k % 10, k /= 10;        while( num )             putchar( c[num--]+48 );        putchar( 10 );    }    int main(){freopen("a.in","r",stdin);freopen("a.out","w",stdout); n = getint(); m = getint();for (int i = 1; i <= n; i++) sum[i] = siz[i] = Multi[i] = va[i] = 1;for (int i = 1; i < n; i++) Join(getint(),getint());while (m--) {scanf("%s",com);int x = getint(),y = getint();if (com[0] == '+') {int c = getint(); add(x,y,c);}else if (com[0] == '-') {Cut(x,y); x = getint(); y = getint();Join(x,y);}else if (com[0] == '*') {int c = getint(); multi(x,y,c);}else print(Query(x,y));}return 0;}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 点击华为设置闪退怎么办 小白摄像头获取视频文件失败怎么办 为什么解压文件老提示失败怎么办 b站sd卡写入失败怎么办 手机检测不到sd卡怎么办 华为sd卡不可用怎么办 u盘延缓写入失败怎么办 手机提示sd卡不可用怎么办 显示sd卡不可用怎么办 小米手机检测不到sd卡怎么办 小米手机sd卡写入失败怎么办 没有检测到sd卡怎么办 e站图片配额用尽怎么办 内存卡密码忘了怎么办 电脑上酷狗音乐播放失败怎么办 播放失败不支持该文件怎么办 手机山寨云资源失效怎么办 支付密码输错了怎么办 微信密码锁定了怎么办 电脑网易云音乐闪退怎么办 逆战耳机电流声怎么办 肠道感染一直吃药治不好怎么办 如果24小时以后还没到账该怎么办 在游戏平台充值没到账该怎么办 充值豪华黄钻没到账该怎么办 起点签到签满了怎么办 ipad锁屏声音小怎么办 扣扣邮箱文件超大了怎么办 网易邮箱图片已过期怎么办 邮箱里面的文件过期了怎么办 邮箱发的文件过期了怎么办 邮箱发送的文件过期怎么办 小米4s开不开机怎么办 小米平板关机后开不开机怎么办 公司老板跑路了社保怎么办 公司老板跑路社保怎么办 公司被公安局查封社保怎么办 小米四开不了机怎么办 小米的手机后壳裂了怎么办 公司没钱拖欠员工社保怎么办 小米note充不进去电怎么办