c++版a+b问题的各种无聊做法

LCT的A+B题解:

#include<iostream>
#include<cstring> #include<cstdio> #include<cstring> using namespace std; struct node { int data,rev,sum; node *son[2],*pre; bool judge(); bool isroot(); void pushdown(); void update(); void setson(node *child,int lr); }lct[233]; int top,a,b; node *getnew(int x) { node *now=lct+ ++top; now->data=x; now->pre=now->son[1]=now->son[0]=lct; now->sum=0; now->rev=0; return now; } bool node::judge(){return pre->son[1]==this;} bool node::isroot() { if(pre==lct)return true; return !(pre->son[1]==this||pre->son[0]==this); } void node::pushdown() { if(this==lct||!rev)return; swap(son[0],son[1]); son[0]->rev^=1; son[1]->rev^=1; rev=0; } void node::update(){sum=son[1]->sum+son[0]->sum+data;} void node::setson(node *child,int lr) { this->pushdown(); child->pre=this; son[lr]=child; this->update(); } void rotate(node *now) { node *father=now->pre,*grandfa=father->pre; if(!father->isroot()) grandfa->pushdown(); father->pushdown();now->pushdown(); int lr=now->judge(); father->setson(now->son[lr^1],lr); if(father->isroot()) now->pre=grandfa; else grandfa->setson(now,father->judge()); now->setson(father,lr^1); father->update();now->update(); if(grandfa!=lct) grandfa->update(); } void splay(node *now) { if(now->isroot())return; for(;!now->isroot();rotate(now)) if(!now->pre->isroot()) now->judge()==now->pre->judge()?rotate(now->pre):rotate(now); } node *access(node *now) { node *last=lct; for(;now!=lct;last=now,now=now->pre) { splay(now); now->setson(last,1); } return last; } void changeroot(node *now) { access(now)->rev^=1; splay(now); } void connect(node *x,node *y) { changeroot(x); x->pre=y; access(x); } void cut(node *x,node *y) { changeroot(x); access(y); splay(x); x->pushdown(); x->son[1]=y->pre=lct; x->update(); } int query(node *x,node *y) { changeroot(x); node *now=access(y); return now->sum; } int main() { scanf("%d%d",&a,&b); node *A=getnew(a); node *B=getnew(b); //连边 Link connect(A,B); //断边 Cut cut(A,B); //再连边orz Link again connect(A,B); printf("%d\n",query(A,B)); return 0; }

Splay:

代码送上

#include <bits/stdc++.h>
#define ll long long #define N 100000 using namespace std; int sz[N], rev[N], tag[N], sum[N], ch[N][2], fa[N], val[N]; int n, m, rt, x; void push_up(int x){ sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1; sum[x] = sum[ch[x][1]] + sum[ch[x][0]] + val[x]; } void push_down(int x){ if(rev[x]){ swap(ch[x][0], ch[x][1]); if(ch[x][1]) rev[ch[x][1]] ^= 1; if(ch[x][0]) rev[ch[x][0]] ^= 1; rev[x] = 0; } if(tag[x]){ if(ch[x][1]) tag[ch[x][1]] += tag[x], sum[ch[x][1]] += tag[x]; if(ch[x][0]) tag[ch[x][0]] += tag[x], sum[ch[x][0]] += tag[x]; tag[x] = 0; } } void rotate(int x, int &k){ int y = fa[x], z = fa[fa[x]]; int kind = ch[y][1] == x; if(y == k) k = x; else ch[z][ch[z][1]==y] = x; fa[x] = z; fa[y] = x; fa[ch[x][!kind]] = y; ch[y][kind] = ch[x][!kind]; ch[x][!kind] = y; push_up(y); push_up(x); } void splay(int x, int &k){ while(x != k){ int y = fa[x], z = fa[fa[x]]; if(y != k) if(ch[y][1] == x ^ ch[z][1] == y) rotate(x, k); else rotate(y, k); rotate(x, k); } } int kth(int x, int k){ push_down(x); int r = sz[ch[x][0]]+1; if(k == r) return x; if(k < r) return kth(ch[x][0], k); else return kth(ch[x][1], k-r); } void split(int l, int r){ int x = kth(rt, l), y = kth(rt, r+2); splay(x, rt); splay(y, ch[rt][1]); } void rever(int l, int r){ split(l, r); rev[ch[ch[rt][1]][0]] ^= 1; } void add(int l, int r, int v){ split(l, r); tag[ch[ch[rt][1]][0]] += v; val[ch[ch[rt][1]][0]] += v; push_up(ch[ch[rt][1]][0]); } int build(int l, int r, int f){ if(l > r) return 0; if(l == r){ fa[l] = f; sz[l] = 1; return l; } int mid = l + r >> 1; ch[mid][0] = build(l, mid-1, mid); ch[mid][1] = build(mid+1, r, mid); fa[mid] = f; push_up(mid); return mid; } int asksum(int l, int r){ split(l, r); return sum[ch[ch[rt][1]][0]]; } int main(){ //总共两个数 n = 2; rt = build(1, n+2, 0);//建树 for(int i = 1; i <= n; i++){ scanf("%d", &x); add(i, i, x);//区间加 } rever(1, n);//区间翻转 printf("%d\n", asksum(1, n));//区间求和 return 0; }
最后是楼主最喜欢的妹子

转载于:https://www.cnblogs.com/lsjjz/p/7405645.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值