BZOJ 3223 & 区间翻转

题意:

  就是贴个代码,这是我入门题的弱化版。。然而一共还是写了40分钟,不专注(一边看比赛一边打)是一个问题,splay每个操作的细节确实有点多(什么时候updata啊。。什么时候pushdown啊。。先后顺序啊)。。还是专注一点尽量一次写出,调代码太折磨了。

CODE:

/*==========================================================================
# Last modified: 2016-02-21 19:13
# Filename: bz3223.cpp
# Description: 
==========================================================================*/
#define me AcrossTheSky 
#include <cstdio> 
#include <cmath> 
#include <ctime> 
#include <string> 
#include <cstring> 
#include <cstdlib> 
#include <iostream> 
#include <algorithm> 
  
#include <set> 
#include <map> 
#include <stack> 
#include <queue> 
#include <vector> 
 
#define lowbit(x) (x)&(-x) 
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
#define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
#define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
#define ls(a,b) (((a)+(b)) << 1) 
#define rs(a,b) (((a)+(b)) >> 1) 
#define getlc(a) ch[(a)][0] 
#define getrc(a) ch[(a)][1] 
 
#define maxn 200000 
#define maxm 100000 
#define pi 3.1415926535898 
#define _e 2.718281828459 
#define INF 1070000000 
using namespace std; 
typedef long long ll; 
typedef unsigned long long ull; 
 
template<class T> inline 
void read(T& num) { 
    bool start=false,neg=false; 
    char c; 
    num=0; 
    while((c=getchar())!=EOF) { 
        if(c=='-') start=neg=true; 
        else if(c>='0' && c<='9') { 
            start=true; 
            num=num*10+c-'0'; 
        } else if(start) break; 
    } 
    if(neg) num=-num; 
} 
/*==================split line==================*/ 
int n,m;
int ch[maxn][2],s[maxn],flip[maxn],fa[maxn];
int root,null=0;

void updata(int node){s[node]=s[getlc(node)]+s[getrc(node)]+1;}
void pushdown(int node){
	if (!flip[node]) return;
	flip[node]=0;
	swap(getlc(node),getrc(node));
	flip[getlc(node)]^=1; flip[getrc(node)]^=1;
}
int build(int l,int r){
	if (l>r) return 0;
	if (l==r) { s[l]=1;	return l;}
	int mid=rs(l,r);
	fa[ch[mid][0]=build(l,mid-1)]=mid; fa[ch[mid][1]=build(mid+1,r)]=mid;
	updata(mid);
	return mid;
}
void rotate(int x){
	int p=fa[x],q=fa[p],d=ch[p][1]==x;
	pushdown(x); pushdown(p);
	fa[ch[p][d]=ch[x][d^1]]=p; updata(p);
	fa[ch[x][d^1]=p]=x; updata(x);
	fa[x]=q;
	if (q){
		if (getlc(q)==p) getlc(q)=x;
		else if (getrc(q)==p) getrc(q)=x;
		updata(q);
	}
}
void splay(int x,int &aim){
	for (int y; (y=fa[x])!=aim;rotate(x))
		if (fa[y]!=aim) rotate((getlc(y)==x)==(getrc(fa[y])==y)?y:x);
	updata(x);
	if (aim==0) root=x;
}
int kth(int k,int node){
	int x=node;
	while(x){
		pushdown(x);
		int ss=s[ch[x][0]];
		if (k==ss+1) return x;
		if (k<=ss) x=ch[x][0];
		else x=ch[x][1],k-=ss,k--;
	}
}
void change(int l,int r){
	int node=kth(l,root); splay(node,null); 
	node=kth(r+2,root); splay(node,root);
	flip[getlc(getrc(root))]^=1;
}
void print(int node){
	if(!node) return;
	pushdown(node);
	print(getlc(node));
	if (node!=1 && node!=n+2) printf("%d ",node-1);
	print(getrc(node));
}
int main(){
	read(n); read(m);
	memset(flip,0,sizeof(flip));
	root=build(1,n+2);
	FORP(i,1,m) {
		int l,r; read(l); read(r);
		change(l,r);
	}
	print(root);
}

 

你可能感兴趣的:(BZOJ 3223 & 区间翻转)