zoukankan      html  css  js  c++  java
  • 【不能继续浪啦】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...


  • 相关阅读:
    SystemTap
    在qemu上运行BusyBox
    Initramfs 原理和实践
    在qemu环境中用gdb调试Linux内核
    [转载] 你所不知道的TIME_WAIT和CLOSE_WAIT
    Linux VXLAN
    :not伪类选择器一些错误的写法
    c# 微软小冰-虚拟女友聊天
    Django使用表单操作数据库
    Django内置过滤器详解附代码附效果图--附全部内置过滤器帮助文档
  • 原文地址:https://www.cnblogs.com/mjy0724/p/4613780.html
Copyright © 2011-2022 走看看