zoukankan      html  css  js  c++  java
  • BZOJ-1500 [NOI2005]维修数列

    神级数据结构维护题。。。Splay练手题。

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #define rep(i, l, r) for(int i=l; i<=r; i++)
    #define clr(x, c) memset(x, c, sizeof(x))
    #define inf 1000000000
    #define maxn 1000005
    using namespace std;
    inline int read()
    {
    	int x=0, f=1; char ch=getchar();
    	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    	return x*f;
    }
    int c[maxn][2], h[maxn], size[maxn], sum[maxn], ls[maxn], rs[maxn], ms[maxn], v[maxn], rt, id[maxn], a[maxn];
    int cnt;
    char s[10];
    bool rev[maxn], tag[maxn];
    queue <int> q;
    inline void update(int x)
    {
    	int l=c[x][0], r=c[x][1];
    	sum[x]=sum[l]+sum[r]+v[x];
    	size[x]=size[l]+size[r]+1;
    	ms[x]=max(ms[l], ms[r]);
    	ms[x]=max(ms[x], rs[l]+v[x]+ls[r]);
    	ls[x]=max(ls[l], sum[l]+v[x]+ls[r]);
    	rs[x]=max(rs[r], rs[l]+v[x]+sum[r]);
    }
    void pushdown(int x)
    {
    	int l=c[x][0], r=c[x][1];
    	if (tag[x])
    	{
    		rev[x]=tag[x]=0;
    		if (l) tag[l]=1, v[l]=v[x], sum[l]=v[l]*size[l];
    		if (r) tag[r]=1, v[r]=v[x], sum[r]=v[r]*size[r];
    		if (v[x]>=0)
    		{
    			if (l) ls[l]=rs[l]=ms[l]=sum[l];
    			if (r) ls[r]=rs[r]=ms[r]=sum[r];
    		}
    		else 
    		{
    			if (l) ls[l]=rs[l]=0, ms[l]=v[l];
    			if (r) ls[r]=rs[r]=0, ms[r]=v[r];
    		}
    	}
    	if (rev[x])
    	{
    		rev[x]^=1; rev[l]^=1; rev[r]^=1;
    		swap(ls[l], rs[l]); swap(ls[r], rs[r]);
    		swap(c[l][0], c[l][1]); swap(c[r][0], c[r][1]);
    	}
    }
    inline void rotate(int x, int &k)
    {
    	int y=h[x], z=h[y], l=(c[y][1]==x), r=l^1;
    	if (y==k) k=x; else c[z][c[z][1]==y]=x;
    	h[c[x][r]]=y, h[y]=x, h[x]=z;
    	c[y][l]=c[x][r]; c[x][r]=y;
    	update(y), update(x);
    }
    inline void Splay(int x, int &k)
    {
    	/* while (x!=k)
    	{
    		int y=h[x], z=h[y];
    		if (y!=k)
    		{
    			(c[y][0]==x)^(c[z][0]==y) ? rotate(x, k) : rotate(y, k);
    		}
    		rotate(x, k);
    	} */
    	while (x!=k) rotate(x, k);
    }
    int Find(int x, int k)
    {
    	pushdown(x);
    	int l=c[x][0], r=c[x][1];
    	if (size[l]+1==k) return x;
    	if (size[l]>=k) return Find(l, k);
    	return Find(r, k-size[l]-1);
    }
    void Del(int x)
    {
    	if (!x) return;
    	int l=c[x][0], r=c[x][1];
    	Del(l); Del(r); q.push(x);
    	h[x]=c[x][0]=c[x][1]=0;
    	tag[x]=rev[x]=0;
    }
    inline int Split(int k, int n)
    {
    	int x=Find(rt, k), y=Find(rt, k+n+1);
    	Splay(x, rt); Splay(y, c[x][1]);
    	return c[y][0];
    }
    inline void QSum(int k, int n){int x=Split(k, n); printf("%d
    ", sum[x]);}
    inline void Same(int k, int n, int val)
    {
    	int x=Split(k, n), y=h[x];
    	v[x]=val; tag[x]=1; sum[x]=size[x]*val;
    	if (val>=0) ls[x]=rs[x]=ms[x]=sum[x]; else ls[x]=rs[x]=0, ms[x]=val;
    	update(y), update(h[y]);
    }
    inline void Rever(int k, int n)
    {
    	int x=Split(k, n), y=h[x];
    	if (tag[x]) return;
    	rev[x]^=1;
    	swap(c[x][0], c[x][1]);
    	swap(ls[x], rs[x]);
    	update(y), update(h[y]);
    }
    inline void Delete(int k, int n)
    {
    	int x=Split(k, n), y=h[x];
    	Del(x); c[y][0]=0; 
    	update(y), update(h[y]);
    }
    void Build(int l, int r, int f)
    {
    	if (l>r) return;
    	int mid=(l+r)>>1, now=id[mid], last=id[f];
    	if (l==r)
    	{
    		sum[now]=a[l], size[now]=1, tag[now]=rev[now]=0;
    		if (a[l]>=0) ls[now]=rs[now]=ms[now]=a[l]; else ls[now]=rs[now]=0, ms[now]=a[l];
    	}
    	else Build(l, mid-1, mid), Build(mid+1, r, mid);
    	v[now]=a[mid], h[now]=last, update(now);
    	c[last][mid>f]=now;
    }
    inline void Insert(int k, int n)
    {
    	rep(i, 1, n) a[i]=read();
    	rep(i, 1, n) if (!q.empty()) id[i]=q.front(), q.pop(); else id[i]=++cnt;
    	Build(1, n, 0); 
    	int x=Find(rt, k+1), y=Find(rt, k+2), z=id[(1+n)>>1];
    	Splay(x, rt); Splay(y, c[x][1]);
    	h[z]=y, c[y][0]=z;
    	update(y), update(x);
    }
    int main()
    {
    	int n=read(), m=read(); 
    	ms[0]=a[1]=a[n+2]=-inf;
    	rep(i, 1, n) a[i+1]=read();
    	rep(i, 1, n+2) id[i]=i;
    	Build(1, n+2, 0);
    	rt=(n+3)>>1, cnt=n+2;
    	rep(i, 1, m)
    	{
    		scanf("%s", s);
    		if (s[0]=='I') 
    			{int a=read(), b=read(); Insert(a, b);}
    		else if (s[0]=='D')
    			{int a=read(), b=read(); Delete(a, b);}
    		else if (s[0]=='R')
    			{int a=read(), b=read(); Rever(a, b);}
    		else if (s[0]=='G')
    			{int a=read(), b=read(); QSum(a, b);}
    		else if (s[2]=='K')
    			{int a=read(), b=read(); Same(a, b, read());}
    		else
    			printf("%d
    ", ms[rt]);
    	}
    	return 0;
    }
  • 相关阅读:
    文件操作函数
    sublime text2 常用快捷键
    过滤掉字段为空的数据
    PHP安装memcache扩展接口步骤
    大数据的逻辑,其实是中医的逻辑
    大数据的逻辑,其实是中医的逻辑
    SPSS输出结果如何在word中设置小数点前面显示加0
    SPSS输出结果如何在word中设置小数点前面显示加0
    掌握4个有效的数据分析要点,切实解决用户痛点
    掌握4个有效的数据分析要点,切实解决用户痛点
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4479626.html
Copyright © 2011-2022 走看看