数据结构
数据结构这种东西敲起来十分爽
数据结构往往替代了我们思考的过程,但还是比较好用的
虽然STL已经内置了很多数据结构,但是NOIP不开O2。。。。。
所以很慢很慢很慢。。。。。nlogn会变成n^2,。。。。所以还是自己写吧
从最基本的开始
队列(队列是一种先进先出的数据结构)
//加入操作
inline void push_up(int x){
q[++tail]=x;
}
//取队列最前端的元素
inline int top(){
return q[head];
}
//删除队列最前面的元素并返回元素
inline void pop(){
return q[head++];
}
//判断队列是否为空
inline bool empty(){
if(head<=tail) return true;
else return false;
}
栈(栈与队列不同,废话名字都不一样,栈是维护先进后出的一种数据结构)
//加入操作
inline void push_up(int x){
q[++top]=x;
}
//取栈最顶端的元素
inline int top(){
return q[top];
}
//删除栈最前面的元素并返回元素
inline void pop(){
return q[--top];
}
有关树的结构
树状数组(树状数组是维护动态区间和的一个极有利的数据结构)
inline lowbit(int x){
return x&-x;
}
inline void insert(int x){
while(x<MAXN){
c[x]+=v;
x+=lowbit(x);
}
}
inline long long search(int x){
long long sum;
while(x){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
平衡树(Treep版本)
void update(int &root) {T[root].siz=T[T[root].leftt].siz+T[T[root].rightt].siz+T[root].weight;}
void left_rote(int &root){
int tmp=T[root].rightt;T[root].rightt=T[tmp].leftt;T[tmp].leftt=root;
T[tmp].siz=T[root].siz;update(root);root=tmp;
}
void right_rote(int &root){
int tmp=T[root].leftt;T[root].leftt=T[tmp].rightt;T[tmp].rightt=root;
T[tmp].siz=T[root].siz;update(root);root=tmp;
}
void insert(int &root,int x){
if(root==0) {tol++;root=tol;T[root].siz=T[root].weight=1;T[root].v=x;T[root].have=rand();return;}
T[root].siz++;
if(T[root].v==x) {T[root].weight++;return;}
if(x>T[root].v){
insert(T[root].rightt,x);
if(T[root].have<T[T[root].rightt].have) left_rote(root);
}
else{
insert(T[root].leftt,x);
if(T[T[root].leftt].have>T[root].have) right_rote(root);
}
}
void delte(int &root,int x){
if(root==0) return;
if(x==T[root].v){
if(T[root].weight>1) {T[root].weight--;T[root].siz--;return;}
else{
if(T[root].leftt*T[root].rightt==0) root=T[root].leftt+T[root].rightt;
else{
if(T[T[root].leftt].have<T[T[root].rightt].have) {right_rote(root);delte(root,x);}
else {left_rote(root);delte(root,x);}
}
}
}
T[root].siz--;
if(x<T[root].v) delte(T[root].leftt,x);
else delte(T[root].rightt,x);
}
void nxt(int root,int x){
if(root==0) return;
if(T[root].v>=x) {tmp=T[root].v;nxt(T[root].leftt,x);}
else nxt(T[root].rightt,x);
}
平衡树(Splay版本)
#include <bits/stdc++.h>
#define inf 10000010
#define ll long long
using namespace std;
inline int read(){
int x=0;int 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;
}
const int MAXN=1e6+10;
namespace Splay{
struct splaytree{
int son[2],siz,delta,v,fa,id,rev,key,maxn;
}T[MAXN];
int tot,root,n,m,sz=0;
inline void update(int x){
if(x){
T[x].siz=1;
if(T[x].son[0]) T[x].siz+=T[T[x].son[0]].siz;
if(T[x].son[1]) T[x].siz+=T[T[x].son[1]].siz;
T[x].maxn=T[x].v;
if(T[x].son[1]) T[x].maxn=max(T[x].maxn,T[T[x].son[1]].maxn);
if(T[x].son[0]) T[x].maxn=max(T[x].maxn,T[T[x].son[0]].maxn);
}
}
inline void push_up(int x){
if(T[x].delta!=0){
T[T[x].son[0]].delta+=T[x].delta;T[T[x].son[1]].delta+=T[x].delta;
T[T[x].son[0]].v+=T[x].delta;T[T[x].son[1]].v+=T[x].delta;
T[T[x].son[0]].maxn+=T[x].delta;T[T[x].son[1]].maxn+=T[x].delta;
T[x].delta=0;
}
if(T[x].rev){
swap(T[x].son[0],T[x].son[1]);
T[T[x].son[1]].rev^=T[x].rev;
T[T[x].son[0]].rev^=T[x].rev;
T[x].rev=0;
}
}
inline int getfather(int x){
return x==T[T[x].fa].son[1];
}
inline void rota(int x){
int oldl=T[x].fa;int oldf=T[oldl].fa;int wei=getfather(x);
T[oldl].son[wei]=T[x].son[wei^1];T[T[x].son[wei^1]].fa=oldl;
T[x].son[wei^1]=oldl;T[oldl].fa=x;T[x].fa=oldf;
if(oldf){
T[oldf].son[oldl==T[oldf].son[1]]=x;
}
update(oldl);update(x);
}
inline void splay(int x,int tal){
for(int fa;(fa=T[x].fa)!=tal;rota(x)){
if(T[fa].fa!=tal){
rota(getfather(x)==getfather(fa)?fa:x);
}
}
if(tal==0) root=x;
}
inline int find(int x){
int now=root;
while(1){
push_up(now);
if(x<=T[T[now].son[0]].siz){
now=T[now].son[0];
}
else{
x-=T[T[now].son[0]].siz+1;
if(x==0) return now;
now=T[now].son[1];
}
}
}
inline int build(int leftt,int rightt,int root){
if(leftt>rightt) return 0;
int mid=(leftt+rightt)>>1;
int now=++sz;
T[now].fa=root;
T[now].id=mid;T[now].delta=0;T[now].v=0;T[now].rev=0;T[now].delta=0;T[now].maxn=0;
int lefttchild=build(leftt,mid-1,now);
int righttchild=build(mid+1,rightt,now);
T[now].son[0]=lefttchild;T[now].son[1]=righttchild;
update(now);
return now;
}
inline void insert(int leftt,int rightt,int vv){
leftt=find(leftt);rightt=find(rightt+2);
splay(leftt,0);splay(rightt,leftt);
int now=T[rightt].son[0];
T[now].delta+=vv; T[now].v+=vv;T[now].maxn+=vv;
}
inline void getmax(int leftt,int rightt){
leftt=find(leftt);rightt=find(rightt+2);
splay(leftt,0);splay(rightt,leftt);
int now=T[rightt].son[0];
printf("%d\n",T[now].maxn);
}
inline void reserve(int leftt,int rightt){
if(leftt>=rightt) return;
leftt=find(leftt);rightt=find(rightt+2);
splay(leftt,0);splay(rightt,leftt);
int now=T[rightt].son[0];
T[now].rev^=1;
}
inline void print(){
for(int i=1;i<=n+2;i++){
cout<<T[i].fa<<' '<<T[i].v<<' '<<T[i].id<<' '<<T[i].maxn<<endl;
}
}
void init(){
n=read();m=read();
root=build(1,n+2,0);
}
void solve(){
while(m--){
int vv=read();
if(vv==1){
int leftt=read();int rightt=read();int vv=read();
insert(leftt,rightt,vv);
}
if(vv==2){
int leftt=read();int rightt=read();
reserve(leftt,rightt);
}
if(vv==3){
int leftt=read();int rightt=read();
getmax(leftt,rightt);
}
}
}
}
int main(){
//freopen("All.in","r",stdin);
//freopen("a.out","w",stdout);
using namespace Splay;
init();
solve();
return 0;
}
线段树(单点修改)
void buildtree(int left,int right,int root)
{
if(yy<left||yy>right) return;
if(left==right) {tree[root].maxn=vv;return;}
int mid=(left+right)/2;
buildtree(left,mid,root*2);
buildtree(mid+1,right,root*2+1);
tree[root].maxn=max(tree[root*2].maxn,tree[root*2+1].maxn);
}
int searchtree(int left,int right,int root)
{
int mid,templ,tempr;
if(yy>right||vv<left) return -20000000;
if(yy<=left&&vv>=right) return tree[root].maxn;
mid=(right+left)/2;
templ=searchtree(left,mid,root*2);
tempr=searchtree(mid+1,right,root*2+1);
return max(templ,tempr);
}
View Code
线段树(区间修改)
void buildtree(int left,int right,int root)
{
if(x>right||y<left) return;
if(x<=left&&y>=right)
{
tree[root].delta++;
tree[root].maxx++;
return;
}
int mid=(left+right)/2;
int delta=tree[root].delta;
tree[root*2].delta+=delta;tree[root*2].maxx+=delta;
tree[root*2+1].delta+=delta;tree[root*2+1].maxx+=delta;
tree[root].delta=0;
buildtree(left,mid,root*2);
buildtree(mid+1,right,root*2+1);
tree[root].maxx=max(tree[root*2].maxx,tree[root*2+1].maxx);
}
int searchtree(int left,int right,int root)
{
if(y<left||x>right) return -2000000;
if(x<=left&&y>=right) return tree[root].maxx;
int mid=(left+right)/2;
int delta=tree[root].delta;
tree[root*2].delta+=delta;tree[root*2].maxx+=delta;
tree[root*2+1].delta+=delta;tree[root*2+1].maxx+=delta;
tree[root].delta=0;
int templ=searchtree(left,mid,root*2);
int tempr=searchtree(mid+1,right,root*2+1);
return max(templ,tempr);
}
树链剖分
void dfs1(int father,int node,int depth){
siz[node]=1;fa[node]=father;dep[node]=depth;son[node]=0;int maxxn=0;
for(int i=linkk[node];i;i=e[i].next){
if(e[i].y!=father){
dfs1(node,e[i].y,depth+1);
if(siz[e[i].y]>maxxn) son[node]=e[i].y,maxxn=siz[e[i].y];
siz[node]+=siz[e[i].y];
}
}
//cout<<siz[node]<<endl;
}
void dfs2(int node,int id){
cnt[node]=++tot;Node[tot]=node;top[node]=id;
if(son[node]) dfs2(son[node],id);
for(int i=linkk[node];i;i=e[i].next){
if(e[i].y!=fa[node]&&e[i].y!=son[node])
dfs2(e[i].y,e[i].y);
}
}
void buildtree(int l,int r,int root){
if(l==r) {T[root].sum=1;if(l==1) T[root].sum=0;return;}
int mid=(l+r)>>1;
buildtree(l,mid,root<<1);
buildtree(mid+1,r,root<<1|1);
T[root].sum=T[root<<1].sum+T[root<<1|1].sum;
}
void insertt(int l,int r,int root){
if(l>x||r<x) return;
if(l==r) {T[root].sum=0;return;}
int mid=(l+r)>>1;
insertt(l,mid,root<<1);
insertt(mid+1,r,root<<1|1);
T[root].sum=T[root<<1].sum+T[root<<1|1].sum;
}
int find(int l,int r,int root){
if(l>=x&&r<=y) return T[root].sum;
if(l>y||r<x) return 0;
int mid=(r+l)>>1;
return find(l,mid,root<<1)+find(mid+1,r,root<<1|1);
}
void init(){
n=read();
for(int i=1;i<n;i++){
int xx=read();int yy=read();
insert(xx,yy);
insert(yy,xx);
}
dfs1(0,1,0);
dfs2(1,1);
buildtree(1,n,1);
}
int search(int node){
if(node==1) return 0;
int ans=0;
while(top[node]!=1){
x=cnt[top[node]];
y=cnt[node];
ans+=find(1,n,1);
node=fa[top[node]];
}
if(node==1) return ans;
y=cnt[node];
x=cnt[top[node]];
ans+=find(1,n,1);
return ans;
}
主席树(不带修改的区间第k大)
#include <bits/stdc++.h>
#define inf 1e9
#define eps 1e-7
using namespace std;
inline int read(){
int x=0;int 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;
}
const int MAXN=100010;
int a[4*MAXN],ans[4*MAXN];
int rsum;
struct node{
int sum,L,R;
}T[MAXN<<5];
int pos;
int cut=0;
int root[4*MAXN]={};
int n,m;
namespace ZHANGENMING{
void inint(){
cin>>n>>m;
for(int i=1;i<=n;i++){
a[i]=ans[i]=read();
}
sort(a+1,a+n+1);
rsum=unique(a+1,a+n+1)-(a+1);
}
int newnode(int id){
T[++cut].sum=T[id].sum+1;
T[cut].L=T[id].L;
T[cut].R=T[id].R;
return cut;
}
int getnow(int s,int t,int rankk,int leftt,int rightt){
if(leftt==rightt) return leftt;
int sum=T[T[t].L].sum-T[T[s].L].sum;
int mid=(leftt+rightt)>>1;
if(sum>=rankk) return getnow(T[s].L,T[t].L,rankk,leftt,mid);
else return getnow(T[s].R,T[t].R,rankk-sum,mid+1,rightt);
}
void insert(int leftt,int rightt,int &root,int id){
root=newnode(id);
if(leftt==rightt) return;
int mid=(leftt+rightt)>>1;
if(pos<=mid) insert(leftt,mid,T[root].L,T[id].L);
else insert(mid+1,rightt,T[root].R,T[id].R);
}
void solve(){
for(int i=1;i<=n;i++){
pos=lower_bound(a+1,a+rsum+1,ans[i])-a;
insert(1,rsum,root[i],root[i-1]);
}
for(int i=1;i<=m;i++){
int ll=read();int rr=read();int kk=read();
int t=getnow(root[ll-1],root[rr],kk,1,rsum);
printf("%d\n",a[t]);
}
}
}
int main(){
using namespace ZHANGENMING;
inint();
solve();
return 0;
}
主席树(带修改的区间第k大)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int x=0;int 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;
}
const int MAXN=5e5+10;
struct Chair_Man_Tree{
int son[2],sum;
}T[MAXN];
struct node{
int a,b,k;
char op;
}Q[MAXN];
int arr[MAXN],fsort[MAXN],root[MAXN],rsum=0,sum=0,n,m,cnt=0,top[2],prevL[MAXN],prevR[MAXN];
namespace zhangenming{
inline int lowbit(int x) {return x&-x;}
void init(){
n=read();m=read();
sum=n;
for(int i=1;i<=n;i++){
fsort[i]=arr[i]=read();
}
for(int i=1;i<=m;i++){
char op[5];
scanf("%s",op);
Q[i].op=op[0];Q[i].a=read();Q[i].b=read();
if(op[0]=='Q') Q[i].k=read();
else fsort[++sum]=Q[i].b;
}
sort(fsort+1,fsort+sum+1);
rsum=unique(fsort+1,fsort+sum+1)-fsort-1;
}
inline int Newnode(int sum,int son0,int son1){
T[++cnt].sum=sum;T[cnt].son[0]=son0;
T[cnt].son[1]=son1;return cnt;
}
inline void build(int &root,int last,int pos,int leftt,int rightt){
root=Newnode(T[last].sum+1,T[last].son[0],T[last].son[1]);
if(leftt==rightt) return;
int mid=(rightt+leftt)>>1;
if(pos<=mid) build(T[root].son[0],T[last].son[0],pos,leftt,mid);
else build(T[root].son[1],T[last].son[1],pos,mid+1,rightt);
}
inline int Get(int leftt,int rightt,int rnk){
if(leftt==rightt) return leftt;
int summ=0;
for(int i=1;i<=top[0];i++) summ-=T[T[prevL[i]].son[0]].sum;
for(int i=1;i<=top[1];i++) summ+=T[T[prevR[i]].son[0]].sum;
int mid=(leftt+rightt)>>1;
if(rnk<=summ){
for(int i=1;i<=top[0];i++) prevL[i]=T[prevL[i]].son[0];
for(int i=1;i<=top[1];i++) prevR[i]=T[prevR[i]].son[0];
return Get(leftt,mid,rnk);
}
else{
for(int i=1;i<=top[0];i++) prevL[i]=T[prevL[i]].son[1];
for(int i=1;i<=top[1];i++) prevR[i]=T[prevR[i]].son[1];
return Get(mid+1,rightt,rnk-summ);
}
}
int k=0;
inline void insert(int leftt,int rightt,int &root,int pos,int val){
if(!root) root=Newnode(0,0,0);
T[root].sum+=val;
if(leftt==rightt) return;
int mid=(rightt+leftt)>>1;
if(pos<=mid) insert(leftt,mid,T[root].son[0],pos,val);
else insert(mid+1,rightt,T[root].son[1],pos,val);
}
void solve(){
for(int i=1;i<=n;i++){
arr[i]=lower_bound(fsort+1,fsort+rsum+1,arr[i])-fsort;
build(root[i+n],root[i+n-1],arr[i],1,rsum);
}
for(int i=1;i<=m;i++){
if(Q[i].op=='Q'){
top[0]=top[1]=0;
prevL[++top[0]]=root[((Q[i].a-1)==0?0:Q[i].a+n-1)];
prevR[++top[1]]=root[Q[i].b+n];
for(int j=Q[i].a-1;j>=1;j-=lowbit(j)){
prevL[++top[0]]=root[j];
}
for(int j=Q[i].b;j>=1;j-=lowbit(j)){
prevR[++top[1]]=root[j];
}
printf("%d\n",fsort[Get(1,rsum,Q[i].k)]);
}
else{
for(int j=Q[i].a;j<=n;j+=lowbit(j)){
insert(1,rsum,root[j],arr[Q[i].a],-1);
}
arr[Q[i].a]=lower_bound(fsort+1,fsort+1+rsum,Q[i].b)-fsort;
for(int j=Q[i].a;j<=n;j+=lowbit(j)){
insert(1,rsum,root[j],arr[Q[i].a],1);
}
}
}
}
}
int main(){
//freopen("All.in","r",stdin);
//freopen("bai.out","w",stdout);
using namespace zhangenming;
init();
solve();
return 0;
}

浙公网安备 33010602011771号