http://acm.hdu.edu.cn/showproblem.php?pid=1698
题意:第一行输入测试组数,第二行输入 n ,表示有个 n 打的区间,第三行输入 m , 表示有 m 个更新,接着输入 m 行,每行三个数 l , r , val, 表示把 l 到 r 这个区间里的所有值改成 val。
最后输出整个区间的权值之和。
可以用线段树解决, 但是我要继续splay
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct Tree{
int lazy;
int pre, chd[2];
int val, sum, Size;
};
const int maxn = 100005;
int n, m;
Tree tr[maxn];
int F(int rt){
return tr[tr[rt].pre].chd[1] == rt;
}
inline int PushUp(int rt)
{
tr[tr[rt].chd[0]].pre = rt;
tr[tr[rt].chd[1]].pre = rt;
tr[rt].Size = tr[tr[rt].chd[0]].Size + tr[tr[rt].chd[1]].Size + 1;
tr[rt].sum = tr[rt].val + tr[tr[rt].chd[0]].sum + tr[tr[rt].chd[1]].sum;
}
inline int PushDown(int rt)
{
if(tr[rt].lazy){
tr[tr[rt].chd[0]].val = tr[rt].lazy;
tr[tr[rt].chd[1]].val = tr[rt].lazy;
tr[tr[rt].chd[0]].lazy = tr[rt].lazy;
tr[tr[rt].chd[1]].lazy = tr[rt].lazy;
tr[tr[rt].chd[0]].sum = tr[tr[rt].chd[0]].Size * tr[tr[rt].chd[0]].val;
tr[tr[rt].chd[1]].sum = tr[tr[rt].chd[1]].Size * tr[tr[rt].chd[1]].val;
tr[rt].lazy = 0;
}
}
void Rotate(int rt)
{
int chd = F(rt);
int pre = tr[rt].pre;
tr[rt].pre = tr[pre].pre;
tr[tr[pre].pre].chd[F(pre)] = rt;
tr[pre].chd[chd] = tr[rt].chd[!chd];
tr[rt].chd[!chd] = pre;
PushUp(pre);
PushUp(rt);
}
int Splay(int rt, int rw)
{
while(tr[rw].pre != rt){
int pre = tr[rw].pre;
if(F(rw) != F(pre) || tr[pre].pre == rt){
Rotate(rw);
}
else{
Rotate(pre);
Rotate(rw);
}
}
if(rt)
PushUp(rt);
return rw;
}
int Find(int rt, int pos) //这题没有区间转移,这个函数只是用来更新lazy
{
int ret = 0;
PushDown(rt);
if(tr[tr[rt].chd[0]].Size == pos - 1)
ret = rt;
else if(tr[tr[rt].chd[0]].Size >= pos)
ret = Find(tr[rt].chd[0], pos);
else
ret = Find(tr[rt].chd[1], pos - tr[tr[rt].chd[0]].Size - 1);
PushUp(rt);
return ret;
}
inline void SetTree(int pos, int val, int lazy, int chd0, int chd1, int pre, int sum, int Size){
tr[pos].val = val;
tr[pos].lazy = lazy;
tr[pos].chd[0] = chd0;
tr[pos].chd[1] = chd1;
tr[pos].pre = pre;
tr[pos].sum =sum;
tr[pos].Size = Size;
}
int BuildTree(int Size)
{
for(int i = 1; i <= Size; i++){
SetTree(i, 1, 0, 0, i + 1, i - 1, Size - i + 1, Size - i + 1);
}
SetTree(0, 0, 0, 0, 0, 0, 0, 0);
SetTree(1, 0, 0, 0, 2, 0, Size, Size);
SetTree(Size, 0, 0, 0, 0, Size - 1, 0, 1);
return 1;
}
int main()
{
int Test, rt, tt = 1;
scanf("%d", &Test);
while(Test--){
scanf("%d%d", &n, &m);
int l, r, val;
rt = BuildTree(n + 2);
rt = Splay(0, n + 2);
while(m--){
scanf("%d%d%d", &l, &r, &val);
rt = Splay(0, Find(rt, l));
Splay(rt, Find(rt, r + 2));
tr[tr[tr[rt].chd[1]].chd[0]].val = val;
tr[tr[tr[rt].chd[1]].chd[0]].lazy = val;
tr[tr[tr[rt].chd[1]].chd[0]].sum = tr[tr[tr[rt].chd[1]].chd[0]].Size * val;
PushDown(tr[tr[rt].chd[1]].chd[0]);
PushUp(tr[rt].chd[1]);
PushUp(rt);
}
rt = Splay(0, Find(rt, 1));
Splay(rt, Find(rt, n + 2));
printf("Case %d: The total value of the hook is %d.\n", tt++, tr[tr[tr[rt].chd[1]].chd[0]].sum);
}
return 0;
}