【不能继续浪啦】BZ做题记录[7.01~7.06]

  

  距离上次提交..><居然已经过去一个半月了...

  然后再去看看人家RXDoi..

  

  差距越来越大啦...

  最后更新时间7.06 19:06

  [07.03 21:02]夏令营自修课逃逃真爽...感觉又要继续初中时候数学不听化学不懂的状态了...

  [07.04 21:05]只做出t1的BC还能有两位数的排名挺感动的..以及第一次叉人成功! //似乎是xj的一个原来排在rk1的选手..

  [07.06 19:04]模拟赛犯了一个类似_shi在noip2014的数组类型开错>< 爽...


7.01

BZOJ1061 NOI 2008 志愿者招募 employee Byvoid的题解棒棒棒

网络流的感觉很强但是很难想到这样的方法

将一些不等式处理成一些加和为0的等式,发现因为每个雇员的工作时间是连续的

所以x[i]只会在开始时间的等式中出现一次,结束时间的后一个时刻以负的形式出现一次

用等式右边的值建立与源汇点之间的边,然后点与点之间的边建一下就好啦w

T了六七次..改了六七次...改出了很多类似于没开long long、数组没开够、可以O(n)的连边我用O(nm)连...

最后好像是因为费用流写错了..TAT

  

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define INF 10000000000000007
#define maxn 1010
#define maxm 10010
#define maxe 25000
#define ll long long
using namespace std;
ll c[maxm],v[maxn],w[maxe],cst[maxe],dis[maxn];
int n,m,s,t,e,a[maxm],b[maxm];
int fa[maxe],next[maxe],link[maxn],son[maxe],rec[maxe],opt[maxn],pre[maxn];
bool vis[maxn];
void add(int x,int y,ll z,ll cost){
    fa[++e]=y;next[e]=link[x];link[x]=e;w[e]=z;cst[e]=cost;son[e]=x;rec[e]=e+1;
    fa[++e]=x;next[e]=link[y];link[y]=e;w[e]=0;cst[e]=-cost;son[e]=y;rec[e]=e-1;
}
bool spfa(){
    for (int i=s;i<=t;i++) dis[i]=INF,vis[i]=true;
    dis[s]=0;vis[s]=false;int head=0,tail=1;opt[1]=s;
    while (head!=tail){
        head=(head+1)%maxn;
        for (int x=opt[head],i=link[x];i;i=next[i]) if (w[i]&&dis[x]+cst[i]<dis[fa[i]]){
            dis[fa[i]]=dis[x]+cst[i];pre[fa[i]]=i;
            if (vis[fa[i]]) tail=(tail+1)%maxn,opt[tail]=fa[i],vis[fa[i]]=false;
        }
        vis[opt[head]]=true;
    }
    if (dis[t]!=INF) return true;return false;
}
ll MCMF(){
    ll ans=0;
    while (spfa()){
        int u=t;ll mn=INF;
        while (u!=s) mn=min(mn,w[pre[u]]),u=son[pre[u]];
        u=t;
        while (u!=s) w[pre[u]]-=mn,w[rec[pre[u]]]+=mn,ans+=mn*cst[pre[u]],u=son[pre[u]];
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    memset(c,0,sizeof(c));
    memset(v,0,sizeof(v));
    for (int i=1;i<=n;i++) scanf("%lld",&v[i]);
    for (int i=n+1;i>=1;i--) v[i]=v[i]-v[i-1];
    for (int i=1;i<=m;i++) scanf("%d%d%lld",&a[i],&b[i],&c[i]);
    s=0,t=n+2,e=0;
    for (int i=1;i<=n+1;i++) if (v[i]>0) add(s,i,v[i],0);else add(i,t,-v[i],0);
    for (int i=1;i<=m;i++) add(a[i],b[i]+1,INF,c[i]);
    for (int i=2;i<=n+1;i++) add(i,i-1,INF,0);
    printf("%lld",MCMF());
    return 0;
}

BZOJ3668[Noi2014]起床困难综合症

从高位搞下去就好了...能用0最终得到1的就不用1

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
struct P{
    int x,y;
}a[200010];
int f[200010][32][2];
char s[100];
int main(){
    int n,m;
    char ch,ch2;
    scanf("%d%d",&n,&m);gets(s);
    for (int i=1;i<=n;i++){
        scanf("%c%c%c",&ch,&ch2,&ch2);
        if (ch=='A') a[i].x=0;else
        if (ch=='O') a[i].x=1;else
        if (ch=='X') a[i].x=2;
        scanf("%d",&a[i].y);gets(s);
    }
    for (int i=0;i<=30;i++) f[0][i][0]=0,f[0][i][1]=1;
    for (int i=1;i<=n;i++){
        for (int j=0;j<=30;j++){
            int now=(a[i].y>>j)%2;
            if (a[i].x==0){
                if (now==0) f[i][j][1]=2,f[i][j][0]=min(f[i-1][j][0],f[i-1][j][1]);else
                f[i][j][0]=f[i-1][j][0],f[i][j][1]=f[i-1][j][1];
            }else
            if (a[i].x==1){
                if (now==1) f[i][j][0]=2,f[i][j][1]=min(f[i-1][j][0],f[i-1][j][1]);else
                f[i][j][0]=f[i-1][j][0],f[i][j][1]=f[i-1][j][1]; 
            }else{
                if (now==1) f[i][j][0]=f[i-1][j][1],f[i][j][1]=f[i-1][j][0];else
                f[i][j][0]=f[i-1][j][0],f[i][j][1]=f[i-1][j][1];
            }      
        }
    }
    int res=0,ans=0;
    for (int i=30;i>=0;i--){
        int tmp=f[n][i][1];
        if (tmp!=2){
        if ((res+tmp*(1<<i))<=m){
            res+=tmp*(1<<i);ans+=1<<i;}
        }      
    }
    printf("%d ",ans);
    return 0;
}

7.02

BZOJ3670[Noi2014]动物园

KMP搞搞就好啦~刚开始并没想到可以类似地求出答案然后用了倍增然后T了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define tt 1000000007
#define maxn 1000010
int T,j,p[maxn],f[maxn],n;
char s[maxn];
int main(){   
    scanf("%d",&T);
    while (T--){
        scanf("%s",s+1);n=strlen(s+1);
        j=0;p[1]=0;
        for (int i=2;i<=n;i++){
            while (j&&s[j+1]!=s[i]) j=p[j];
            if (s[j+1]==s[i]) j++;
            p[i]=j;
        }
        j=0;long long ans=1;
        f[0]=0;for (int i=1;i<=n;i++) f[i]=f[p[i]]+1;
        for (int i=1;i<=n;i++){
            while (j&&s[j+1]!=s[i]) j=p[j];
            if (s[j+1]==s[i]) j++;
            while (j>i/2) j=p[j];
            ans=(ans*(f[j]+1))%tt;
        }
        printf("%lld ",ans);
    }
    return 0;
}

BZOJ1497: [NOI2006]最大获利

和文理分科一样..?


7.03

BZOJ1588:[HNOI2002]营业额统计

...数据有问题..pas大法好..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define INF 1000000007
using namespace std;
int n,cnt,root;
struct P{
    int l,r,fa,va;
}tr[1000010];
void rotate(int x){
    int y=tr[x].fa,z=tr[y].fa;
    if (tr[z].l==y) tr[z].l=x;else tr[z].r=x;tr[x].fa=z;
    if (tr[y].l==x){
        tr[y].l=tr[x].r;tr[tr[x].r].fa=y;
        tr[x].r=y;tr[y].fa=x;
    }else{
        tr[y].r=tr[x].l;tr[tr[x].l].fa=y;
        tr[x].l=y;tr[y].fa=x;
    }
    if (y==root) root=x;
}
void splay(int x){
    while (x!=root&&tr[x].fa!=root){
        int y=tr[x].fa,z=tr[y].fa;
        if (!((tr[y].l==x)^(tr[z].l==y))) rotate(y),rotate(x);else rotate(x),rotate(x);
    }
    if (x!=root) rotate(x);
}
void insert(int p,int va){
    if (!root){
        root=++cnt;tr[cnt].va=va;return;
    }
    int las=p;
    while (p){
        las=p;if (va<=tr[p].va) p=tr[p].l;else p=tr[p].r;
    }
    if (va<=tr[las].va) tr[las].l=++cnt;else tr[las].r=++cnt;
    tr[cnt].fa=las;tr[cnt].va=va;
    splay(cnt);
}
int solve(int x){
    if (x==1) return tr[x].va;
    int tmp=INF;
    int y=tr[x].l,las=y;
    while (y){las=y;y=tr[y].r;}tmp=min(tmp,abs(tr[las].va-tr[x].va));
    y=tr[x].r;las=y;
    while (y){las=y;y=tr[y].l;}tmp=min(tmp,abs(tr[las].va-tr[x].va));
    return tmp;   
}
int main(){
    scanf("%d",&n);
    int x,ans=0;
    root=cnt=0;tr[0].va=INF;
    for (int i=1;i<=n;i++) {
        x=0;
        scanf("%d",&x);    
        insert(root,x);
        ans+=solve(cnt);
    }
    printf("%d",ans);
    return 0;
}

BZOJ2882: 工艺

又是一道做过的题w

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define INF 1000000007
#define N 1200010
using namespace std;
int n,a[N],s[N],tmp[N],rank[N],sa[N];
void suffix_array(){
    int sz=N;
    for (int i=0;i<n;i++) rank[i]=a[i];
    for (int i=0;i<sz;i++) s[i]=0;
    for (int i=0;i<n;i++) s[rank[i]]++;
    for (int i=1;i<sz;i++) s[i]+=s[i-1];
    for (int i=n-1;i>=0;i--) sa[--s[rank[i]]]=i;
    for (int j=1;j<=n/4;j*=2){
        int p=0;
        for (int i=n-j;i<n;i++) tmp[p++]=i;
        for (int i=0;i<n;i++) if (sa[i]-j>=0) tmp[p++]=sa[i]-j;
        for (int i=0;i<sz;i++) s[i]=0;
        for (int i=0;i<n;i++) s[rank[i]]++;
        for (int i=1;i<sz;i++) s[i]+=s[i-1];
        for (int i=n-1;i>=0;i--) sa[--s[rank[tmp[i]]]]=tmp[i];
        p=0;tmp[sa[0]]=0;
        for (int i=1;i<n;i++){
            int v0=sa[i-1],v1=sa[i],v00,v01;
            if (v0+j<n) v00=rank[v0+j];else v00=-1;
            if (v1+j<n) v01=rank[v1+j];else v01=-1;
            if (rank[v0]==rank[v1]&&v00==v01) tmp[sa[i]]=p;else tmp[sa[i]]=++p;
        }
        for (int i=0;i<n;i++) rank[i]=tmp[i];
    }
}
int main(){
    scanf("%d",&n);
    for (int i=0;i<4*n;i++) a[i]=N/2;
    for (int i=0;i<n;i++) scanf("%d",&a[i]),a[n+i]=a[i];
    n*=4;suffix_array();   
    for (int i=sa[0];i-sa[0]<(n/4)-1;i++) printf("%d ",a[i]);
    printf("%d",a[sa[0]+(n/4)-1]);
    return 0;
}

BZOJ1208: [HNOI2004]宠物收养所

删除刚开始写错了...还检查出了一些各种各样的错误 但是最终A掉了感觉好爽><

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define tt 1000000
using namespace std;
int n,root,cnt,v0,v1;
long long ans;
struct P{
    int l,r,fa,va;
}tr[80010];
void rotate(int x){
    int y=tr[x].fa,z=tr[y].fa;
    if (tr[z].l==y) tr[z].l=x;else tr[z].r=x;tr[x].fa=z;
    if (tr[y].l==x){
        tr[y].l=tr[x].r;tr[tr[x].r].fa=y;
        tr[x].r=y;tr[y].fa=x;
    }else{
        tr[y].r=tr[x].l;tr[tr[x].l].fa=y;
        tr[x].l=y;tr[y].fa=x;
    }
    if (y==root) root=x;
}
void splay(int x){
    while (x!=root&&tr[x].fa!=root){
        int y=tr[x].fa,z=tr[y].fa;
        if (!((tr[y].l==x)^(tr[z].l==y))) rotate(y),rotate(x);else rotate(x),rotate(x);
    }
    if (x!=root) rotate(x);  
}
void insert(int p,int va){
    if (!root){
        root=++cnt;tr[cnt].va=va;tr[cnt].l=tr[cnt].r=tr[cnt].fa=0;return;
    }
    int las=p;
    while (p){las=p;if (va<=tr[p].va) p=tr[p].l;else p=tr[p].r;}
    if (va<=tr[las].va) tr[las].l=++cnt;else tr[las].r=++cnt;tr[cnt].fa=las;
    tr[cnt].va=va;tr[cnt].l=tr[cnt].r=0;splay(cnt);
}
void del(int x){
    if (tr[x].l==0||tr[x].r==0){
        int y=tr[x].fa,z=tr[x].l+tr[x].r;
        if (tr[y].l==x) tr[y].l=z;else tr[y].r=z;tr[z].fa=y;
        if (root==x) root=z;
        if (y) splay(y);
        return;
    }
    int las=tr[x].r,p=tr[x].r;
    while (p){las=p;p=tr[p].l;}
    while (las!=tr[x].r&&tr[las].fa!=tr[x].r){
        int y=tr[las].fa,z=tr[y].fa;
        if (!((tr[y].l==las)^(tr[z].l==y))) rotate(y),rotate(las);else rotate(las),rotate(las);     
    }
    if (las!=tr[x].r) rotate(las);
    int y=tr[x].fa;if (tr[y].l==x) tr[y].l=las;else tr[y].r=las;tr[las].fa=y;
    y=tr[x].l;tr[las].l=y;tr[y].fa=las;
    if (root==x) root=las;   
    splay(las);    
}
void calc(int x){
    int x1,x2,y;
    insert(root,x);    
    int las=tr[cnt].l,p=tr[cnt].l;
    while (p){las=p;p=tr[p].r;}x1=las;
    las=tr[cnt].r,p=tr[cnt].r;
    while (p){las=p;p=tr[p].l;}x2=las;
    if (x1==0||(x2!=0&&x-tr[x1].va>tr[x2].va-x)) y=x2;else y=x1;
    ans=(ans+abs(tr[y].va-x))%tt;
    del(cnt);del(y);
    if (v0) v0--;else v1--; 
}
int main(){
    scanf("%d",&n);
    v0=0,v1=0;root=0;cnt=0;ans=0;
    int x,y;
    for (int i=1;i<=n;i++){
        scanf("%d%d",&y,&x);
        if (!y){
            if (!v1) insert(root,x),v0++;else calc(x);
        }else{
            if (!v0) insert(root,x),v1++;else calc(x);
        }
    }
    printf("%d",ans);
    return 0;
}

7.04

BZOJ1251: 序列终结者

整个下午只调了这一道题...WA了8次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define INF 0x7fffffff
using namespace std;
struct P{
    int l,r,add,va,rev,fa,s;
    long long mx,ave;
}tr[50010];
int n,m,root,cnt;
void pushdown(int x){
    if (!x) return//!!! 
    int l=tr[x].l,r=tr[x].r;
    if (tr[x].add){       
        int c=tr[x].add;tr[l].ave+=c;tr[r].ave+=c;tr[l].mx+=c;tr[r].mx+=c;
        tr[l].add+=c;tr[r].add+=c;tr[x].add=0;
    }
    if (tr[x].rev){       
        tr[x].l=r;tr[x].r=l;tr[l].rev=tr[l].rev^1;tr[r].rev=tr[r].rev^1;tr[x].rev=0; 
    }
}
void pushup(int x){
    if (!x) return//!!! 
    int l=tr[x].l,r=tr[x].r;
    tr[x].s=tr[l].s+tr[r].s+1;
    tr[x].mx=max(tr[x].ave,max(tr[l].mx,tr[r].mx));
}
void rotate(int x){  
    int y=tr[x].fa,z=tr[y].fa;
    pushdown(z);pushdown(y);pushdown(x);//(*) 
    if (tr[z].l==y) tr[z].l=x;else tr[z].r=x;tr[x].fa=z;
    if (tr[y].l==x){
        tr[y].l=tr[x].r;tr[tr[x].r].fa=y;
        tr[x].r=y;tr[y].fa=x;
    }else{
        tr[y].r=tr[x].l;tr[tr[x].l].fa=y;
        tr[x].l=y;tr[y].fa=x;
    }
    if (y==root) root=x;
    pushup(y); // (*) 
}
void splay(int x,int t){
    pushdown(x);//尽管去掉这句还是可以A但是感觉如果tr[x].fa==t的话整个过程直接pushup(x)不是就出问题了? 
    while (tr[x].fa!=t&&tr[tr[x].fa].fa!=t){
        int y=tr[x].fa,z=tr[y].fa;    
        if (!((tr[y].l==x)^(tr[z].l==y))) rotate(y),rotate(x);       
        else rotate(x),rotate(x);
    }
    if (tr[x].fa!=t) rotate(x);
    pushup(x);
}
void insert(int p,int va,int ave){
    if (!root){
        root=++cnt;tr[cnt].va=va;tr[cnt].ave=ave;tr[cnt].rev=tr[cnt].mx=tr[cnt].add=0;tr[cnt].s=1;return;
    }
    int las;
    while (p){
        las=p;tr[p].s++;if (va<tr[p].va) p=tr[p].l;else p=tr[p].r;
    }
    if (va<tr[las].va) tr[las].l=++cnt;else tr[las].r=++cnt;tr[cnt].fa=las;
    tr[cnt].va=va;tr[cnt].ave=ave;tr[cnt].rev=tr[cnt].mx=tr[cnt].add=0;tr[cnt].s=1;
    splay(cnt,0);
}
int find(int p,int q){
    pushdown(p); //rev标记会改变树的结构所以一定要记得pd!! 
    int l=tr[p].l,r=tr[p].r;
    if (tr[l].s+1==q) return p;
    if (tr[l].s+1>q) return find(l,q);else return find(r,q-tr[l].s-1);
}
int main(){
    scanf("%d%d",&n,&m);
    root=cnt=0;tr[0].mx=-INF;
    int c,l,r,x,y;long long z;
    insert(root,1,-INF); //自己加进去的点赋的权值不能影响答案的计算 
    for (int i=2;i<=n+1;i++) insert(root,i,0);
    insert(root,n+2,-INF);
    for (int i=1;i<=m;i++){
        scanf("%d",&c);
        if (c==1){
            scanf("%d%d%lld",&l,&r,&z);l++;r++;
            int x=find(root,l-1),y=find(root,r+1);
            splay(x,0);splay(y,x);
            tr[tr[y].l].add+=z;tr[tr[y].l].ave+=z;tr[tr[y].l].mx+=z;   
        }
        if (c==2){
            scanf("%d%d",&l,&r);l++;r++;
            int x=find(root,l-1),y=find(root,r+1);
            splay(x,0);splay(y,x);
            tr[tr[y].l].rev=tr[tr[y].l].rev^1;
        }
        if (c==3){
            scanf("%d%d",&l,&r);l++;r++;
            int x=find(root,l-1),y=find(root,r+1);
            splay(x,0);splay(y,x); 
            printf("%d ",tr[tr[y].l].mx);
        }      
    }
    return 0;
}

7.05

BZOJ1861: [Zjoi2006]Book 书架

现在做这道题就比较轻松啦 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int root,n,m;
char s[100];
struct P{
    int l,r,fa,ave,s;
}tr[80010];
void pushup(int x){if (!x) return;tr[x].s=tr[tr[x].l].s+tr[tr[x].r].s+1;}
void rotate(int x){
    int y=tr[x].fa,z=tr[y].fa;
    if (tr[z].l==y) tr[z].l=x;else tr[z].r=x;tr[x].fa=z;
    if (tr[y].l==x){
        tr[y].l=tr[x].r;tr[tr[x].r].fa=y;
        tr[x].r=y;tr[y].fa=x;
    }else{
        tr[y].r=tr[x].l;tr[tr[x].l].fa=y;
        tr[x].l=y;tr[y].fa=x;
    }
    pushup(y);if (root==y) root=x;
}
void splay(int x,int t){
    while (tr[x].fa!=t&&tr[tr[x].fa].fa!=t){
        int y=tr[x].fa,z=tr[y].fa;
        if (!((tr[y].l==x)^(tr[z].l==y))) rotate(y),rotate(x);else rotate(x),rotate(x);
    }
    if (tr[x].fa!=t) rotate(x);pushup(x);if (t) pushup(t);
}
void insert(int p,int x){
    if (!root){root=x;tr[x].s=1;tr[x].l=tr[x].r=tr[x].fa=0;return;}
    int las;  
    while (p){    
        las=p;tr[p].s++;if (tr[x].ave<tr[p].ave) p=tr[p].l;else p=tr[p].r;
    }
    if (tr[x].ave<tr[las].ave) tr[las].l=x;else tr[las].r=x;tr[x].fa=las;tr[x].s=1;
    tr[x].l=tr[x].r=0;
    splay(x,0);
}
void del(int x){
    if (tr[x].l==0||tr[x].r==0){
        int y=tr[x].l+tr[x].r,z=tr[x].fa;
        if (tr[z].l==x) tr[z].l=y;else tr[z].r=y;tr[y].fa=z;if (z) pushup(z);
        if (root==x) root=y;        //!!!!
    }else{
        int las,p=tr[x].r;
        while (p){las=p;p=tr[p].l;}splay(las,x);
        int y=tr[x].fa;if (tr[y].l==x) tr[y].l=las;else tr[y].r=las;tr[las].fa=y;if (y) pushup(y);
        y=tr[x].l;tr[y].fa=las;tr[las].l=y;pushup(las);
        if (root==x) root=las;       //!!!!
    }
    int y=tr[x].fa;   
    if (y) splay(y,0);
}
int get(int p,int k){
    if (!p) return 0;
    int l=tr[p].l,r=tr[p].r;
    if (tr[p].ave==k) return tr[l].s+1;else
        if (tr[p].ave<k) return tr[l].s+1+get(r,k);else return get(l,k);
}
int find(int p,int k){
    int l=tr[p].l,r=tr[p].r;
    if (tr[l].s+1==k) return p;else
        if (tr[l].s>=k) return find(l,k);else return find(r,k-tr[l].s-1);
}
int main(){
    scanf("%d%d",&n,&m);
    root=0;int lx=1,rx=n,x,y;char ch;
    for (int i=1;i<=n;i++) scanf("%d",&x),tr[x].ave=i;
    for (int i=1;i<=n;i++) insert(root,i);gets(s);
    for (int i=1;i<=m;i++){
        scanf("%c",&ch);
        if (ch=='T'){
            scanf("%c%c%d",&ch,&ch,&x);
            del(x);tr[x].ave=--lx;insert(root,x);
        }
        if (ch=='B'){
            scanf("%c%c%c%c%c%d",&ch,&ch,&ch,&ch,&ch,&x);
            del(x);tr[x].ave=++rx;insert(root,x);
        }
        if (ch=='I'){
            scanf("%c%c%c%c%c%d%d",&ch,&ch,&ch,&ch,&ch,&x,&y);
            if (y!=0){
                int tmp=get(root,tr[x].ave);tmp=find(root,tmp+y);
                swap(tr[x].ave,tr[tmp].ave);
                del(x);insert(root,x);del(tmp);insert(root,tmp);
            }
        }
        if (ch=='A'){
            scanf("%c%c%d",&ch,&ch,&x);
            printf("%d ",get(root,tr[x].ave)-1);
        }
        if (ch=='Q'){
            scanf("%c%C%c%c%d",&ch,&ch,&ch,&ch,&x);
            printf("%d ",find(root,x));
        }gets(s);
    }
    return 0;
}

下午没什么事发现了第7板的一波水题然后开始切..没切几道就不想切啦..

居然有好多在初一的时候老师就给我们做过呢..

印象很深刻的题是因为当时大家都觉得解法很好很难想到

w...


原文地址:https://www.cnblogs.com/mjy0724/p/4613780.html