zoukankan      html  css  js  c++  java
  • 【算法总结】数据结构

    【splay】

    〖模板代码

     1 void rotate(int x,int& k)
     2 {
     3     int y=fa[x],z=fa[y],l,r;
     4     l=(tr[y][1]==x);r=l^1;
     5     if(y==k)k=x;
     6     else tr[z][tr[z][1]==y]=x;
     7     fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
     8     tr[y][l]=tr[x][r];tr[x][r]=y;
     9     update(y);update(x);
    10 }
    11 void splay(int x,int &k)
    12 {
    13     while(x!=k)
    14     {
    15         int y=fa[x],z=fa[y];
    16         if(y!=k)
    17         {
    18             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
    19             else rotate(y,k);
    20         }
    21         rotate(x,k);
    22     }
    23 }
    View Code

    〖相关题目

    1.【bzoj3786】星系探索

    题意:见原题

    分析:Zsnuoの博客

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 using namespace std;
      5 const int inf=0x3f3f3f3f;
      6 const int N=100010;
      7 struct node{int ch[2],size,fa,t,num;long long v,sum,tag;}tr[N<<1];
      8 struct edge{int next,to;}e[N];
      9 int n,m,f,root,cnt;
     10 int head[N],q[N<<1],s[N];
     11 int read()
     12 {
     13     int x=0,f=1;char c=getchar();
     14     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     15     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     16     return x*f;
     17 }
     18 void insert(int a,int b){cnt++;e[cnt].to=b;e[cnt].next=head[a];head[a]=cnt;}
     19 void dfs(int x)
     20 {
     21     q[++cnt]=x+1;
     22     for(int i=head[x];i;i=e[i].next)dfs(e[i].to);
     23     q[++cnt]=x+n+1;
     24 }
     25 void pushup(int x)
     26 {
     27     int l=tr[x].ch[0],r=tr[x].ch[1];
     28     tr[x].size=tr[l].size+tr[r].size+1;
     29     tr[x].num=tr[l].num+tr[r].num+tr[x].t;
     30     tr[x].sum=tr[l].sum+tr[r].sum+tr[x].v;
     31 }
     32 void pushdown(int x)
     33 {
     34     int l=tr[x].ch[0],r=tr[x].ch[1];long long tag=tr[x].tag;
     35     if(l)tr[l].tag+=tag,tr[l].sum+=tag*tr[l].num,tr[l].v+=tag*tr[l].t;
     36     if(r)tr[r].tag+=tag,tr[r].sum+=tag*tr[r].num,tr[r].v+=tag*tr[r].t;
     37     tr[x].tag=0;
     38 }
     39 void rotate(int x,int& k)
     40 {
     41     int y=tr[x].fa,z=tr[y].fa,l,r;
     42     if(tr[y].ch[0]==x)l=0;else l=1;r=l^1;
     43     if(y==k)k=x;
     44     else{if(tr[z].ch[0]==y)tr[z].ch[0]=x;else tr[z].ch[1]=x;}
     45     tr[x].fa=z;tr[y].fa=x;tr[tr[x].ch[r]].fa=y;
     46     tr[y].ch[l]=tr[x].ch[r];tr[x].ch[r]=y;
     47     pushup(y);pushup(x);
     48 }
     49 void splay(int x,int& k)
     50 {
     51     int top=0;s[++top]=x;
     52     for(int i=x;tr[i].fa;i=tr[i].fa)s[++top]=tr[i].fa;
     53     for(int i=top;i;i--)if(tr[s[i]].tag)pushdown(s[i]);
     54     while(x!=k)
     55     {
     56         int y=tr[x].fa,z=tr[y].fa;
     57         if(y!=k)
     58         {
     59             if((tr[y].ch[0]==x)^(tr[z].ch[0]==y))rotate(x,k);
     60             else rotate(y,k);
     61         }
     62         rotate(x,k);
     63     }
     64 }
     65 int fmin(int x){while(tr[x].ch[0])x=tr[x].ch[0];return x;}
     66 int fmax(int x){while(tr[x].ch[1])x=tr[x].ch[1];return x;}
     67 void split(int l,int r)
     68 {
     69     splay(l,root);int x=fmax(tr[l].ch[0]);
     70     splay(r,root);int y=fmin(tr[r].ch[1]);
     71     splay(x,root);splay(y,tr[x].ch[1]);
     72 }
     73 void build(int l,int r,int last)
     74 {
     75     if(l>r)return;
     76     int mid=(l+r)>>1;
     77     tr[q[mid]].fa=q[last];
     78     tr[q[last]].ch[mid>last]=q[mid];
     79     build(l,mid-1,mid);build(mid+1,r,mid);
     80     pushup(q[mid]);
     81 }
     82 void print(int x)
     83 {
     84     printf("[%d] [fa]%d [v]%lld [sum]%lld [t]%d [num]%d
    ",x,tr[x].fa,tr[x].v,tr[x].sum,tr[x].t,tr[x].num);
     85     int l=tr[x].ch[0],r=tr[x].ch[1];
     86     if(l)print(l);if(r)print(r);
     87 }
     88 void query()
     89 {
     90     int x=read();
     91     splay(x+1,root);
     92     printf("%lld
    ",tr[tr[x+1].ch[0]].sum+tr[x+1].v);
     93 }
     94 void change()
     95 {
     96     int x=read(),y=read();
     97     split(x+1,x+n+1);
     98     int yi=tr[root].ch[1],xi=tr[yi].ch[0];
     99     tr[yi].ch[0]=0;pushup(yi);pushup(root);
    100     splay(y+1,root);
    101     int u=fmin(tr[y+1].ch[1]);
    102     splay(u,tr[y+1].ch[1]);
    103     tr[xi].fa=u;
    104     tr[u].ch[0]=xi;
    105     pushup(u);pushup(root);
    106 }
    107 void add()
    108 {
    109     int x=read();long long tag=read();
    110     split(x+1,x+n+1);
    111     int yi=tr[root].ch[1],xi=tr[yi].ch[0];
    112     tr[xi].tag+=tag;tr[xi].sum+=tag*tr[xi].num;tr[xi].v+=tag*tr[xi].t;
    113     pushup(yi);pushup(root);
    114 }
    115 int main()
    116 {
    117     char str[1];
    118     n=read();
    119     for(int i=2;i<=n;i++)f=read(),insert(f,i);
    120     for(int i=1;i<=n;i++)f=read(),tr[i+1].v=f,tr[i+1].t=1,tr[i+n+1].v=-f,tr[i+n+1].t=-1;
    121     cnt=1;dfs(1);root=q[n+1];
    122     q[1]=1;q[2*n+2]=2*n+2;
    123     build(1,2*n+2,0);
    124     m=read();
    125     while(m--)
    126     {
    127         scanf("%s",str);
    128         if(str[0]=='Q')query();
    129         if(str[0]=='C')change();
    130         if(str[0]=='F')add();
    131     }
    132     return 0;
    133 }
    View Code
      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 using namespace std;
      5 const int N=100010;
      6 struct node{int ch[2],fa,t,num;long long v,sum,tag;}tr[N<<1];
      7 struct edge{int next,to;}e[N];
      8 int n,m,f,root,cnt;
      9 int head[N],q[N<<1],s[N<<1];
     10 int read()
     11 {
     12     int x=0,f=1;char c=getchar();
     13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     14     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     15     return x*f;
     16 }
     17 void insert(int a,int b){cnt++;e[cnt].to=b;e[cnt].next=head[a];head[a]=cnt;}
     18 void dfs(int x)
     19 {
     20     q[++cnt]=x+1;
     21     for(int i=head[x];i;i=e[i].next)dfs(e[i].to);
     22     q[++cnt]=x+n+1;
     23 }
     24 void add(int x,long long tag){tr[x].sum+=tag*tr[x].num;tr[x].v+=tag*tr[x].t;}
     25 void pushup(int x)
     26 {
     27     int l=tr[x].ch[0],r=tr[x].ch[1];
     28     tr[x].num=tr[l].num+tr[r].num+tr[x].t;
     29     tr[x].sum=tr[l].sum+tr[r].sum+tr[x].v;
     30 }
     31 void pushdown(int x)
     32 {
     33     int l=tr[x].ch[0],r=tr[x].ch[1];long long tag=tr[x].tag;
     34     if(l)tr[l].tag+=tag,add(l,tag);
     35     if(r)tr[r].tag+=tag,add(r,tag);
     36     tr[x].tag=0;
     37 }
     38 void rotate(int x,int& k)
     39 {
     40     int y=tr[x].fa,z=tr[y].fa,l,r;
     41     if(tr[y].ch[0]==x)l=0;else l=1;r=l^1;
     42     if(y==k)k=x;
     43     else{if(tr[z].ch[0]==y)tr[z].ch[0]=x;else tr[z].ch[1]=x;}
     44     tr[x].fa=z;tr[y].fa=x;tr[tr[x].ch[r]].fa=y;
     45     tr[y].ch[l]=tr[x].ch[r];tr[x].ch[r]=y;
     46     pushup(y);pushup(x);
     47 }
     48 void splay(int x,int& k)
     49 {
     50     int top=0;s[++top]=x;
     51     for(int i=x;tr[i].fa;i=tr[i].fa)s[++top]=tr[i].fa;
     52     for(int i=top;i;i--)if(tr[s[i]].tag)pushdown(s[i]);
     53     while(x!=k)
     54     {
     55         int y=tr[x].fa,z=tr[y].fa;
     56         if(y!=k)
     57         {
     58             if((tr[y].ch[0]==x)^(tr[z].ch[0]==y))rotate(x,k);
     59             else rotate(y,k);
     60         }
     61         rotate(x,k);
     62     }
     63 }
     64 int find(int x){while(tr[x].ch[1])x=tr[x].ch[1];return x;}
     65 void build(int l,int r,int last)
     66 {
     67     if(l>r)return;
     68     int mid=(l+r)>>1;
     69     tr[q[mid]].fa=q[last];
     70     tr[q[last]].ch[mid>last]=q[mid];
     71     build(l,mid-1,mid);build(mid+1,r,mid);
     72     pushup(q[mid]);
     73 }
     74 int merge(int r1,int r2)
     75 {
     76     int w=find(r1);
     77     splay(w,r1);
     78     tr[w].ch[1]=r2;
     79     tr[r2].fa=w;
     80     pushup(w);
     81     return w;
     82 }
     83 void cutl(int x,int rt,int& r1,int& r2)
     84 {
     85     splay(x,rt);
     86     r1=tr[x].ch[0];r2=x;
     87     tr[x].ch[0]=0;
     88     tr[r1].fa=0;
     89     pushup(x);
     90 }
     91 void cutr(int x,int rt,int& r1,int& r2)
     92 {
     93     splay(x,rt);
     94     r1=x;r2=tr[x].ch[1];
     95     tr[x].ch[1]=0;
     96     tr[r2].fa=0;
     97     pushup(x);
     98 }
     99 void query()
    100 {
    101     int x=read()+1;
    102     splay(x,root);
    103     printf("%lld
    ",tr[tr[x].ch[0]].sum+tr[x].v);
    104 }
    105 void change()
    106 {
    107     int x=read()+1,y=x+n,k=read()+1,p1,p2,p3;
    108     cutl(x,root,p1,p2);
    109     cutr(y,p2,p2,p3);
    110     cutr(k,merge(p1,p3),p1,p3);
    111     root=merge(merge(p1,p2),p3);
    112 }
    113 void add()
    114 {
    115     int x=read()+1,y=x+n;long long tag=read();
    116     splay(x,root);splay(y,tr[x].ch[1]);
    117     int z=tr[y].ch[0];
    118     add(x,tag);add(y,tag);
    119     add(z,tag);tr[z].tag+=tag;
    120     pushup(y);pushup(x);
    121 }
    122 int main()
    123 {
    124     char str[5];
    125     n=read();
    126     for(int i=2;i<=n;i++)f=read(),insert(f,i);
    127     for(int i=2;i<=n+1;i++)f=read(),tr[i].v=f,tr[i].t=1,tr[i+n].v=-f,tr[i+n].t=-1;
    128     cnt=0;q[++cnt]=1;dfs(1);q[++cnt]=2*n+2;
    129     build(1,2*n+2,0);root=q[n+1];
    130     m=read();
    131     while(m--)
    132     {
    133         scanf("%s",str);
    134         if(str[0]=='Q')query();
    135         if(str[0]=='C')change();
    136         if(str[0]=='F')add();
    137     }
    138     return 0;
    139 }
    View Code

    2.【bzoj1500】[NOI2005]维修数列

    题意:见原题

    分析:Zsnuoの博客

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<queue>
      5 using namespace std;
      6 const int inf=0x3f3f3f3f;
      7 const int N=1000005;
      8 queue<int>q;
      9 int n,m,root,cnt;
     10 int tr[N][2],id[N],a[N],size[N],sum[N],v[N],mx[N],lx[N],rx[N],fa[N];
     11 bool tag[N],rev[N];
     12 int read()
     13 {
     14     int x=0,f=1;char c=getchar();
     15     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     16     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     17     return x*f;
     18 }
     19 void update(int x)
     20 {
     21     int l=tr[x][0],r=tr[x][1];
     22     sum[x]=sum[l]+sum[r]+v[x];
     23     size[x]=size[l]+size[r]+1;
     24     mx[x]=max(mx[l],mx[r]);
     25     mx[x]=max(mx[x],rx[l]+v[x]+lx[r]);
     26     lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);
     27     rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);
     28 }
     29 void pushdown(int x)
     30 {
     31     int l=tr[x][0],r=tr[x][1];
     32     if(tag[x])
     33     {
     34         rev[x]=tag[x]=0;
     35         if(l)tag[l]=1,v[l]=v[x],sum[l]=v[x]*size[l];
     36         if(r)tag[r]=1,v[r]=v[x],sum[r]=v[x]*size[r];
     37         if(v[x]>=0)
     38         {
     39             if(l)mx[l]=lx[l]=rx[l]=sum[l];
     40             if(r)mx[r]=lx[r]=rx[r]=sum[r];
     41         }
     42         else
     43         {
     44             if(l)lx[l]=rx[l]=0,mx[l]=v[x];
     45             if(r)lx[r]=rx[r]=0,mx[r]=v[x];
     46         }
     47     }
     48     if(rev[x])
     49     {
     50         rev[x]^=1;rev[l]^=1;rev[r]^=1;
     51         swap(lx[l],rx[l]);swap(lx[r],rx[r]);
     52         swap(tr[l][0],tr[l][1]);swap(tr[r][0],tr[r][1]);
     53     }
     54 }
     55 void rotate(int x,int& k)
     56 {
     57     int y=fa[x],z=fa[y],l,r;
     58     l=(tr[y][1]==x);r=l^1;
     59     if(y==k)k=x;
     60     else tr[z][tr[z][1]==y]=x;
     61     fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
     62     tr[y][l]=tr[x][r];tr[x][r]=y;
     63     update(y);update(x);
     64 }
     65 void splay(int x,int& k)
     66 {
     67     while(x!=k)
     68     {
     69         int y=fa[x],z=fa[y];
     70         if(y!=k)
     71         {
     72             if((tr[y][0]==x)^(tr[z][0]==y))rotate(x,k);
     73             else rotate(y,k);
     74         }
     75         rotate(x,k);
     76     }
     77 }
     78 int find(int x,int rnk)
     79 {
     80     pushdown(x);
     81     int l=tr[x][0],r=tr[x][1];
     82     if(size[l]+1==rnk)return x;
     83     else if(size[l]>=rnk)return find(l,rnk);
     84     else return find(r,rnk-size[l]-1);
     85 }
     86 int turn(int k,int tot)
     87 {
     88     int x=find(root,k),y=find(root,k+tot+1);
     89     splay(x,root);splay(y,tr[x][1]);
     90     return tr[y][0];
     91 }
     92 void build(int l,int r,int f)
     93 {
     94     if(l>r)return;
     95     int mid=(l+r)>>1,now=id[mid],last=id[f];
     96     if(l==r)
     97     {
     98         sum[now]=a[l];size[now]=1;tag[now]=rev[now]=0;
     99         if(a[l]>=0)lx[now]=rx[now]=mx[now]=a[l];
    100         else lx[now]=rx[now]=0,mx[now]=a[l];
    101     }
    102     else build(l,mid-1,mid),build(mid+1,r,mid);
    103     v[now]=a[mid];fa[now]=last;update(now);
    104     tr[last][mid>=f]=now;
    105 }
    106 void insert(int k,int tot)
    107 {
    108     for(int i=1;i<=tot;i++)a[i]=read();
    109     for(int i=1;i<=tot;i++)
    110         if(!q.empty())id[i]=q.front(),q.pop();
    111         else id[i]=++cnt;
    112     build(1,tot,0);int rt=id[(1+tot)>>1];
    113     int x=find(root,k+1),y=find(root,k+2);
    114     splay(x,root);splay(y,tr[x][1]);
    115     tr[y][0]=rt;fa[rt]=y;
    116     update(y);update(x);
    117 }
    118 void rec(int x)
    119 {
    120     if(!x)return;
    121     int l=tr[x][0],r=tr[x][1];
    122     rec(l);rec(r);q.push(x);
    123     fa[x]=tr[x][0]=tr[x][1]=0;
    124     tag[x]=rev[x]=0;
    125 }
    126 void erase(int k,int tot)
    127 {
    128     int x=turn(k,tot),y=fa[x];
    129     rec(x);tr[y][0]=0;
    130     update(y);update(fa[y]);
    131 }
    132 void makesame(int k,int tot,int val)
    133 {
    134     int x=turn(k,tot),y=fa[x];
    135     tag[x]=1;v[x]=val;sum[x]=val*size[x];
    136     if(val>=0)lx[x]=rx[x]=mx[x]=sum[x];
    137     else lx[x]=rx[x]=0,mx[x]=val;
    138     update(y);update(fa[y]);
    139 }
    140 void rever(int k,int tot)
    141 {
    142     int x=turn(k,tot),y=fa[x];
    143     if(!tag[x])
    144     {
    145         rev[x]^=1;
    146         swap(tr[x][0],tr[x][1]);
    147         swap(lx[x],rx[x]);
    148         update(y);update(fa[y]);
    149     }
    150 }
    151 void query(int k,int tot)
    152 {
    153     int x=turn(k,tot);
    154     printf("%d
    ",sum[x]);
    155 }
    156 int main()
    157 {
    158     n=read();m=read();
    159     mx[0]=a[1]=a[n+2]=-inf;
    160     for(int i=1;i<=n;i++)a[i+1]=read();
    161     for(int i=1;i<=n+2;i++)id[i]=i;
    162     root=(n+3)>>1;cnt=n+2;
    163     build(1,n+2,0);
    164     int k,tot,val;
    165     char s[15];
    166     while(m--)
    167     {
    168         scanf("%s",s);
    169         if(s[0]!='M'||s[2]!='X')k=read(),tot=read();
    170         if(s[0]=='I')insert(k,tot);
    171         else if(s[0]=='D')erase(k,tot);
    172         else if(s[0]=='M')
    173         {
    174             if(s[2]=='X')printf("%d
    ",mx[root]);
    175             else val=read(),makesame(k,tot,val);
    176         }
    177         else if(s[0]=='R')rever(k,tot);
    178         else query(k,tot);
    179     }
    180     return 0;
    181 }
    View Code

    【treap】

    〖模板代码

     1 void update(int k){tr[k].s=tr[tr[k].l].s+tr[tr[k].r].s+tr[k].w;}
     2 void lturn(int& k)
     3 {
     4     int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k;
     5     tr[t].s=tr[k].s;update(k);k=t;
     6 }
     7 void rturn(int& k)
     8 {
     9     int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k;
    10     tr[t].s=tr[k].s;update(k);k=t;
    11 }
    12 void insert(int& k,int x)
    13 {
    14     if(k==0){k=++cnt;tr[k].w=tr[k].s=1;tr[k].rnd=rand();tr[k].v=x;return;}
    15     tr[k].s++;
    16     if(x==tr[k].v)tr[k].w++;
    17     else if(x<tr[k].v){insert(tr[k].l,x);if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k);}
    18     else {insert(tr[k].r,x);if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k);}
    19 }
    20 void del(int& k,int x)
    21 {
    22     if(k==0)return;
    23     if(tr[k].v==x)
    24     {
    25         if(tr[k].w>1)tr[k].w--,tr[k].s--;
    26         else if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;
    27         else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd)rturn(k),del(k,x);
    28         else lturn(k),del(k,x);
    29     }
    30     else if(x<tr[k].v)tr[k].s--,del(tr[k].l,x);
    31     else tr[k].s--,del(tr[k].r,x);
    32 }
    33 int askrank(int k,int x)
    34 {
    35     if(k==0)return 0;
    36     if(tr[k].v==x)return tr[tr[k].l].s+1;
    37     else if(x<tr[k].v)return askrank(tr[k].l,x);
    38     else return tr[tr[k].l].s+tr[k].w+askrank(tr[k].r,x);
    39 }
    40 int asknum(int k,int x)
    41 {
    42     if(k==0)return 0;
    43     if(x<=tr[tr[k].l].s)return asknum(tr[k].l,x);
    44     else if(x>tr[tr[k].l].s+tr[k].w)return asknum(tr[k].r,x-tr[tr[k].l].s-tr[k].w);
    45     else return tr[k].v;
    46 }
    47 void askbefore(int k,int x)
    48 {
    49     if(k==0)return;
    50     if(tr[k].v<x)ans=tr[k].v,askbefore(tr[k].r,x);
    51     else askbefore(tr[k].l,x);
    52 }
    53 void askafter(int k,int x)
    54 {
    55     if(k==0)return;
    56     if(tr[k].v>x)ans=tr[k].v,askafter(tr[k].l,x);
    57     else askafter(tr[k].r,x);
    58 }
    View Code

    【线段树】

    〖模板代码

     1 void up(int x)
     2 {
     3     sum[x]=sum[l(x)]+sum[r(x)];
     4     mx[x]=max(mx[l(x)],mx[r(x)]);
     5     mn[x]=min(mn[l(x)],mn[r(x)]);
     6 }
     7 void cset(int x,int l,int r,ll mark)
     8 {
     9     set[x]=mark;add[x]=0;f[x]=true;
    10     sum[x]=mark*(r-l+1);
    11     mx[x]=mn[x]=mark;
    12 }
    13 void cadd(int x,int l,int r,ll mark)
    14 {
    15     add[x]+=mark;
    16     sum[x]+=mark*(r-l+1);
    17     mx[x]+=mark;mn[x]+=mark;
    18 }
    19 void start(int x,int l,int r)
    20 {
    21     int mid=(l+r)>>1;
    22     if(f[x])
    23     {
    24         cset(l(x),l,mid,set[x]);
    25         cset(r(x),mid+1,r,set[x]);
    26         set[x]=0;f[x]=false;
    27     }
    28     if(add[x])
    29     {
    30         cadd(l(x),l,mid,add[x]);
    31         cadd(r(x),mid+1,r,add[x]);
    32         add[x]=0;
    33     }
    34 }
    35 void build(int x,int l,int r)
    36 {
    37     if(l==r)
    38     {
    39         sum[x]=read();
    40         mn[x]=mx[x]=sum[x];
    41         return;
    42     }
    43     int mid=(l+r)>>1;
    44     build(l(x),l,mid);
    45     build(r(x),mid+1,r);
    46     if(l!=r)up(x);
    47 }
    48 void change(int x,int l,int r,ll mark,int p)
    49 {
    50     if(l!=r)start(x,l,r);
    51     if(L<=l&&R>=r)
    52     {
    53         if(p==1)cadd(x,l,r,mark);
    54         if(p==2)cset(x,l,r,mark);
    55         return;
    56     }
    57     int mid=(l+r)>>1;
    58     if(L<=mid)change(l(x),l,mid,mark,p);
    59     if(R>mid)change(r(x),mid+1,r,mark,p);
    60     if(l!=r)up(x);
    61 }
    62 void ask(int x,int l,int r,int p)
    63 {
    64     if(l!=r)start(x,l,r);
    65     if(L<=l&&R>=r)
    66     {
    67         if(p==1)ans=max(ans,mx[x]);
    68         if(p==2)ans=min(ans,mn[x]);
    69         if(p==3)ans+=sum[x];
    70         return;
    71     }
    72     int mid=(l+r)>>1;
    73     if(L<=mid)ask(l(x),l,mid,p);
    74     if(R>mid)ask(r(x),mid+1,r,p);
    75 }
    View Code

    〖相关题目

    1.【codeforces788E】New Task

    题意:n个数,初始属性为1。m个操作,每个操作可以改变一个数字的属性为0或1。每次操作后,求有多少子序列满足要求:a<b<c<d<e,且Xa≤Xb=Xc=Xd≥Xe,b,c,d属性为1,a,e属性任意。

    分析:Zsnuoの博客

      1 #include<cstdio>
      2 #include<algorithm> 
      3 #include<cstring>
      4 #define LL long long
      5 using namespace std;
      6 const int N=1e5+10;
      7 const int mod=1e9+7;
      8 int n,m,cnt,sum,x,y,last;
      9 int num[N],t[N],L[N],R[N],root[N],s[N],p[N],ans;
     10 struct node{int w,pos;}a[N];
     11 struct tree{int l,r,sz,s[6];}tr[N*10];
     12 int read()
     13 {
     14     int x=0,f=1;char c=getchar();
     15     while(c<'0'||c>'9'){if(x=='-')f=-1;c=getchar();}
     16     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     17     return x*f;
     18 }
     19 bool cmp(node a,node b){return a.w==b.w?a.pos<b.pos:a.w<b.w;}
     20 int lowbit(int x){return x&(-x);}
     21 void insert(int x)
     22 {
     23     while(x<=n)
     24     {
     25         t[x]++;
     26         x+=lowbit(x);
     27     }
     28 }
     29 int query(int x)
     30 {
     31     int ans=0;
     32     while(x){ans+=t[x];x-=lowbit(x);}
     33     return ans;
     34 }
     35 void up(int x)
     36 {
     37     int l=tr[x].l,r=tr[x].r;
     38     tr[x].sz=(tr[l].sz+tr[r].sz)%mod;
     39     tr[x].s[1]=(tr[l].s[1]+tr[r].s[1])%mod;
     40     tr[x].s[5]=(tr[l].s[5]+tr[r].s[5])%mod;
     41     tr[x].s[2]=(tr[l].s[2]+tr[r].s[2]+(LL)tr[l].s[1]*tr[r].sz)%mod;
     42     tr[x].s[4]=(tr[l].s[4]+tr[r].s[4]+(LL)tr[l].sz*tr[r].s[5])%mod;
     43     tr[x].s[3]=(tr[l].s[3]+tr[r].s[3]+(LL)tr[l].s[1]*tr[r].s[4]+(LL)tr[l].s[2]*tr[r].s[5])%mod;
     44     //LL!!! 
     45 }
     46 void change(int &x,int l,int r,int pos,int v)
     47 {
     48     if(x==0)x=++sum;
     49     if(l==r)
     50     {
     51         tr[x].sz=v*1;
     52         tr[x].s[1]=v*L[pos];
     53         tr[x].s[5]=v*R[pos];
     54         tr[x].s[2]=tr[x].s[3]=tr[x].s[4]=0;
     55         tr[x].l=tr[x].r=0;
     56         return;
     57     }
     58     else
     59     {
     60         int mid=(l+r)>>1;
     61         if(p[pos]<=mid)change(tr[x].l,l,mid,pos,v);
     62         else change(tr[x].r,mid+1,r,pos,v);
     63         up(x);
     64     }
     65 }
     66 int main()
     67 {
     68     n=read();
     69     for(int i=1;i<=n;i++)
     70         a[i].w=read(),a[i].pos=i;
     71     sort(a+1,a+n+1,cmp);
     72     for(int i=1;i<=n;i++)
     73     {
     74         if(a[i].w!=a[i-1].w)
     75         {
     76             if(cnt)s[cnt]=i-1-last;
     77             last=i-1;
     78             cnt++;
     79         }
     80         num[a[i].pos]=cnt;
     81         p[a[i].pos]=i-last;
     82     }
     83     s[cnt]=n-last;
     84     for(int i=1;i<=n;i++)
     85         L[i]=query(num[i]),insert(num[i]);
     86     memset(t,0,sizeof(t));
     87     for(int i=n;i>=1;i--)
     88         R[i]=query(num[i]),insert(num[i]);
     89     for(int i=1;i<=n;i++)
     90     {
     91         ans=(ans-tr[root[num[i]]].s[3]+mod)%mod;
     92         change(root[num[i]],1,s[num[i]],i,1);
     93         ans=(ans+tr[root[num[i]]].s[3])%mod;
     94     }
     95     m=read();
     96     for(int i=1;i<=m;i++)
     97     {
     98         x=read();y=read();
     99         ans=(ans-tr[root[num[y]]].s[3]+mod)%mod;
    100         change(root[num[y]],1,s[num[y]],y,x-1);
    101         ans=(ans+tr[root[num[y]]].s[3])%mod;
    102         printf("%d
    ",ans);
    103     }
    104     return 0;
    105 }
    View Code

    2.【bzoj4756】[Usaco2017 Jan] Promotion Counting

    题意:见原题

    分析:线段树合并的裸题

     1 #include<cstdio>
     2 #include<algorithm> 
     3 #include<cstring>
     4 #define LL long long
     5 using namespace std;
     6 const int N=1e5+10;
     7 int n,cnt,tot;
     8 int id[N],p[N],fa[N],first[N],ans[N],root[N];
     9 int ls[N*100],rs[N*100],tr[N*100];
    10 struct edge{int to,next;}e[N];
    11 int read()
    12 {
    13     int x=0,f=1;char c=getchar();
    14     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    15     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    16     return x*f;
    17 }
    18 void ins(int u,int v){e[++tot]=(edge){v,first[u]};first[u]=tot;}
    19 void insert(int l,int r,int& pos,int num,int w)
    20 {
    21     pos=++cnt;tr[pos]+=w;
    22     if(l==r)return;
    23     int mid=(l+r)>>1;
    24     if(num<=mid)insert(l,mid,ls[pos],num,w);
    25     else insert(mid+1,r,rs[pos],num,w);
    26 }
    27 int merge(int now,int last)
    28 {
    29     if(!now||!last)return now^last;//子树为空就直接并上去 
    30     ls[now]=merge(ls[now],ls[last]);
    31     rs[now]=merge(rs[now],rs[last]);
    32     tr[now]=tr[ls[now]]+tr[rs[now]];
    33     return now;
    34 }
    35 int query(int l,int r,int pos,int L,int R)
    36 {
    37     if(L<=l&&R>=r)return tr[pos];
    38     int sum=0,mid=(l+r)>>1;
    39     if(L<=mid)sum+=query(l,mid,ls[pos],L,R);
    40     if(R>mid)sum+=query(mid+1,r,rs[pos],L,R);
    41     return sum;
    42 }
    43 void dfs(int x)
    44 {
    45     insert(1,n,root[x],id[x],1);
    46     for(int i=first[x];i;i=e[i].next)dfs(e[i].to);
    47     for(int i=first[x];i;i=e[i].next)root[x]=merge(root[x],root[e[i].to]);
    48     ans[x]=query(1,n,root[x],id[x]+1,n);
    49 }
    50 int main()
    51 {
    52     n=read();
    53     for(int i=1;i<=n;i++)id[i]=p[i]=read();
    54     sort(p+1,p+n+1);
    55     for(int i=1;i<=n;i++)id[i]=lower_bound(p+1,p+n+1,id[i])-p;
    56     for(int i=2;i<=n;i++)fa[i]=read(),ins(fa[i],i);
    57     dfs(1);
    58     for(int i=1;i<=n;i++)printf("%d
    ",ans[i]);
    59     return 0;
    60 }
    View Code

    【树状数组】

    〖模板代码

      [单点修改区间查询]

    1 int lowbit(int x){return x&(-x);}
    2 void insert(int x,int p){while(x<=n)t[x]+=p,x+=lowbit(x);}
    3 int query(int x){int ans=0;while(x)ans+=t[x],x-=lowbit(x);return ans;}
    View Code

      [区间修改区间查询]

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #define LL long long
     6 using namespace std;
     7 const int N=1e5+5;
     8 int n,m,op,L,R;
     9 LL tmp,x,tr[N][2];
    10 LL read()
    11 {
    12     LL x=0,f=1;char c=getchar();
    13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    14     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    15     return x*f;
    16 }
    17 int lowbit(int x){return x&(-x);}
    18 void add(int x,LL c,int id){while(x<=n)tr[x][id]+=c,x+=lowbit(x);}
    19 void insert(int id,LL c){add(id,c,0);add(id,c*id,1);}
    20 LL query(int x,int id){LL ans=0;while(x)ans+=tr[x][id],x-=lowbit(x);return ans;}
    21 LL ask(int id){LL ans=(id+1)*query(id,0)-query(id,1);return ans;}
    22 int main()
    23 {
    24     n=read();m=read();
    25     for(int i=1;i<=n;i++)x=read(),insert(i,x-tmp),tmp=x;
    26     while(m--)
    27     {
    28         op=read();
    29         if(op==1)
    30         {
    31             L=read();R=read();x=read();
    32             insert(L,x);insert(R+1,-x);
    33         }
    34         else
    35         {
    36             L=read();R=read();
    37             printf("%lld
    ",ask(R)-ask(L-1));
    38         }
    39     }
    40     return 0;
    41 }
    View Code

    〖相关题目

    1.【bzoj3173】[Tjoi2013]最长上升子序列

    题意:给定一个初始为空的序列,现在将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,求此时最长上升子序列长度。

    分析:Zsnuoの博客

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int N=1e5+5;
     6 int n,id,cnt,f[N],ans[N],a[N],num[N],bit[N];
     7 int read()
     8 {
     9     int x=0,f=1;char c=getchar();
    10     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    11     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    12     return x*f;
    13 }
    14 int lowbit(int x){return x&(-x);}
    15 void ins(int x){while(x<=n)bit[x]--,x+=lowbit(x);}
    16 int pos(int x)
    17 {
    18     int now=0,ans=0;
    19     for(int i=17;i>=0;i--)
    20     {
    21         now+=(1<<i);
    22         if(now<n&&ans+bit[now]<x)ans+=bit[now];
    23         else now-=(1<<i);
    24     }
    25     return now+1;
    26 }
    27 int main()
    28 {
    29     n=read();
    30     for(int i=1;i<=n;i++)
    31     {
    32         a[i]=read();bit[i]++;
    33         if(i+lowbit(i)<=n)bit[i+lowbit(i)]+=bit[i];
    34     }
    35     for(int i=n;i>=1;i--)
    36         id=pos(a[i]+1),num[id]=i,ins(id);
    37     for(int i=1;i<=n;i++)
    38     {
    39         id=lower_bound(f+1,f+cnt+1,num[i])-f;
    40         if(id>cnt)f[++cnt]=num[i];
    41         else f[id]=num[i];
    42         ans[num[i]]=id;
    43     }
    44     for(int i=1;i<=n;i++)ans[i]=max(ans[i],ans[i-1]),printf("%d
    ",ans[i]);
    45     return 0;
    46 }
    View Code

    【堆】

    〖模板代码

     1 int main()
     2 {
     3     n=read();
     4     for(int i=1;i<=n;i++)
     5     {
     6         op=read();
     7         if(op==1)
     8         {
     9             a[++num]=read();tmp=num;
    10             while(tmp!=1)
    11             {
    12                 if(a[tmp]<a[tmp/2])swap(a[tmp],a[tmp/2]);
    13                 else break;tmp>>=1;
    14             }
    15         }
    16         else if(op==2)printf("%d
    ",a[1]);
    17         else
    18         {
    19             a[1]=a[num--];tmp=1;
    20             while(tmp*2<=num)
    21             {
    22                 int next=tmp*2;
    23                 if(a[next]>a[next+1]&&next+1<=num)next++;
    24                 if(a[tmp]<=a[next])break;
    25                 swap(a[tmp],a[next]);tmp=next;
    26             }
    27         }
    28     }
    29 }
    View Code

    【主席树】

    〖相关题目

    1.【bzoj2588】Spoj 10628. Count on a tree

    题意:给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。

    分析:Zsnuoの博客

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define LL long long
     5 using namespace std;
     6 const int N=1e5+5;
     7 int n,m,tot,x,y,rk,cnte,ind,cnt,temp,lastans;
     8 int v[N],tmp[N],first[N],id[N],num[N],root[N];
     9 int deep[N],fa[N][20];
    10 struct node{int lc,rc,sum;}tr[N*20];
    11 struct edge{int to,next;}e[N*2];
    12 int read()
    13 {
    14     int x=0,f=1;char c=getchar();
    15     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    16     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    17     return x*f;
    18 }
    19 void ins(int u,int v){e[++cnte]=(edge){v,first[u]};first[u]=cnte;}
    20 void insert(int u,int v){ins(u,v);ins(v,u);}
    21 void dfs(int x)
    22 {
    23     ind++;id[x]=ind;num[ind]=x;
    24     for(int i=1;(1<<i)<=deep[x];i++)fa[x][i]=fa[fa[x][i-1]][i-1];
    25     for(int i=first[x];i;i=e[i].next)
    26     {
    27         if(deep[e[i].to])continue;
    28         fa[e[i].to][0]=x;deep[e[i].to]=deep[x]+1;dfs(e[i].to);
    29     }
    30 }
    31 int lca(int ri,int rj)
    32 {
    33     if(deep[ri]<deep[rj])swap(ri,rj);
    34     int d=deep[ri]-deep[rj];
    35     for(int i=0;(1<<i)<=d;i++)if((1<<i)&d)ri=fa[ri][i];
    36     if(ri==rj)return ri;
    37     for(int i=17;i>=0;i--)
    38         if((1<<i)<=deep[ri]&&fa[ri][i]!=fa[rj][i])
    39             ri=fa[ri][i],rj=fa[rj][i];
    40     return fa[ri][0];
    41 }
    42 void update(int &x,int last,int L,int R,int num)
    43 {
    44     x=++cnt;tr[x].sum=tr[last].sum+1;
    45     if(L==R)return;
    46     tr[x].lc=tr[last].lc;tr[x].rc=tr[last].rc;
    47     int mid=(L+R)>>1;
    48     if(num<=mid)update(tr[x].lc,tr[last].lc,L,mid,num);
    49     else update(tr[x].rc,tr[last].rc,mid+1,R,num);
    50 }
    51 int query(int x,int y,int rk)
    52 {
    53     int a=x,b=y,c=lca(x,y),d=fa[c][0];
    54     a=root[id[x]];b=root[id[b]];c=root[id[c]];d=root[id[d]];
    55     int L=1,R=tot;
    56     while(L<R)
    57     {
    58         int mid=(L+R)>>1;
    59         temp=tr[tr[a].lc].sum+tr[tr[b].lc].sum-tr[tr[c].lc].sum-tr[tr[d].lc].sum;
    60         if(temp>=rk)R=mid,a=tr[a].lc,b=tr[b].lc,c=tr[c].lc,d=tr[d].lc;
    61         else rk-=temp,L=mid+1,a=tr[a].rc,b=tr[b].rc,c=tr[c].rc,d=tr[d].rc;
    62     }
    63     return tmp[L];
    64 }
    65 int main()
    66 {
    67     n=read();m=read();
    68     for(int i=1;i<=n;i++)v[i]=tmp[i]=read();
    69     sort(tmp+1,tmp+n+1);tot=unique(tmp+1,tmp+n+1)-tmp-1;
    70     for(int i=1;i<=n;i++)v[i]=lower_bound(tmp+1,tmp+tot+1,v[i])-tmp;
    71     for(int i=1;i<n;i++)x=read(),y=read(),insert(x,y);
    72     deep[1]=1;dfs(1);
    73     for(int i=1;i<=n;i++)
    74     {
    75         temp=num[i];
    76         update(root[i],root[id[fa[temp][0]]],1,tot,v[temp]);
    77     }
    78     for(int i=1;i<=m;i++)
    79     {
    80         x=read();y=read();rk=read();x^=lastans;
    81         lastans=query(x,y,rk);printf("%d",lastans);
    82         if(i!=m)printf("
    ");
    83     }
    84     return 0;
    85 }
    View Code

    2.【bzoj3524】[Poi2014]Couriers

    题意:给一个长度为n的序列a,m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。

    分析:主席树裸题

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int N=5e5+5;
     6 int n,m,sz,cnt,tmp,id,Li,Ri,a[N],b[N],rt[N];
     7 struct node{int sum,lc,rc;}tr[N*20];
     8 int read()
     9 {
    10     int x=0,f=1;char c=getchar();
    11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    12     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    13     return x*f;
    14 }
    15 void build(int& root,int L,int R)
    16 {
    17     root=++cnt;tr[root].sum=0;
    18     if(L==R)return;int mid=(L+R)>>1;
    19     build(tr[root].lc,L,mid);build(tr[root].rc,mid+1,R);
    20 }
    21 void up(int& root,int L,int R,int last,int num)
    22 {
    23     root=++cnt;tr[root]=(node){tr[last].sum+1,tr[last].lc,tr[last].rc};
    24     if(L==R)return;int mid=(L+R)>>1;
    25     if(num<=mid)up(tr[root].lc,L,mid,tr[last].lc,num);
    26     else up(tr[root].rc,mid+1,R,tr[last].rc,num);
    27 }
    28 int query(int ql,int qr,int L,int R,int K)
    29 {
    30     if(L==R){if(tr[qr].sum-tr[ql].sum>=K)return L;return 0;}
    31     int mid=(L+R)>>1;
    32     tmp=tr[tr[qr].lc].sum-tr[tr[ql].lc].sum;
    33     if(tmp>=K)return query(tr[ql].lc,tr[qr].lc,L,mid,K);
    34     else return query(tr[ql].rc,tr[qr].rc,mid+1,R,K);
    35 }
    36 void work()
    37 {
    38     Li=read();Ri=read();
    39     id=query(rt[Li-1],rt[Ri],1,sz,(Ri-Li+1)/2+1);
    40     printf("%d
    ",b[id]);
    41 }
    42 int main()
    43 {
    44     n=read();m=read();
    45     for(int i=1;i<=n;i++)a[i]=b[i]=read();
    46     sort(b+1,b+n+1);sz=unique(b+1,b+n+1)-b-1;
    47     build(rt[0],1,sz);
    48     for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+sz+1,a[i])-b;
    49     for(int i=1;i<=n;i++)up(rt[i],1,sz,rt[i-1],a[i]);
    50     while(m--)work();
    51     return 0;
    52 }
    View Code

    3.【bzoj1901】Zju2112 Dynamic Rankings

    题意:给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。

    分析:带修改的主席树

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define LL long long
     5 using namespace std;
     6 const int N=2e4+5;
     7 int n,m,cnt,tot,id,tx,ty;
     8 int A[N],B[N],C[N],a[N],tmp[N],rt[N],xx[N],yy[N];
     9 int lc[N*200],rc[N*200],sum[N*200];
    10 char op[3];
    11 int read()
    12 {
    13     int x=0,f=1;char c=getchar();
    14     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    15     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    16     return x*f;
    17 }
    18 int lowbit(int x){return x&(-x);}
    19 void ins(int& x,int last,int L,int R,int num,int c)
    20 {
    21     x=++tot;lc[x]=lc[last];rc[x]=rc[last];sum[x]=sum[last]+c;
    22     if(L==R)return;int mid=(L+R)>>1;
    23     if(num<=mid)ins(lc[x],lc[last],L,mid,num,c);
    24     else ins(rc[x],rc[last],mid+1,R,num,c);
    25 }
    26 void add(int x,int c)
    27 {
    28     id=lower_bound(tmp+1,tmp+cnt+1,a[x])-tmp;
    29     for(int i=x;i<=n;i+=lowbit(i))ins(rt[i],rt[i],1,cnt,id,c);
    30 }
    31 int query(int L,int R,int num)
    32 {
    33     if(L==R)return L;
    34     int ans=0,mid=(L+R)>>1;
    35     for(int i=1;i<=tx;i++)ans-=sum[lc[xx[i]]];
    36     for(int i=1;i<=ty;i++)ans+=sum[lc[yy[i]]];
    37     if(num<=ans)
    38     {
    39         for(int i=1;i<=tx;i++)xx[i]=lc[xx[i]];
    40         for(int i=1;i<=ty;i++)yy[i]=lc[yy[i]];
    41         return query(L,mid,num);
    42     }
    43     else
    44     {
    45         for(int i=1;i<=tx;i++)xx[i]=rc[xx[i]];
    46         for(int i=1;i<=ty;i++)yy[i]=rc[yy[i]];
    47         return query(mid+1,R,num-ans);
    48     }
    49 }
    50 int main()
    51 {
    52     n=read();m=read();cnt=n;
    53     for(int i=1;i<=n;i++)tmp[i]=a[i]=read();
    54     for(int i=1;i<=m;i++)
    55     {
    56         scanf("%s",op+1);
    57         A[i]=read();B[i]=read();
    58         if(op[1]=='Q')C[i]=read();
    59         else tmp[++cnt]=B[i];
    60     }
    61     sort(tmp+1,tmp+cnt+1);
    62     cnt=unique(tmp+1,tmp+cnt+1)-tmp-1;
    63     for(int i=1;i<=n;i++)add(i,1);
    64     for(int i=1;i<=m;i++)
    65         if(C[i])
    66         {
    67             tx=ty=0;
    68             for(int j=A[i]-1;j;j-=lowbit(j))xx[++tx]=rt[j];
    69             for(int j=B[i];j;j-=lowbit(j))yy[++ty]=rt[j];
    70             printf("%d
    ",tmp[query(1,cnt,C[i])]);
    71         }
    72         else add(A[i],-1),a[A[i]]=B[i],add(A[i],1);
    73     return 0;
    74 }
    View Code

    【fhq-treap】

    〖注意事项

    在split的时候,如果w=0,记得写l=r=0。

    〖模板代码

      [单点插入、单点删除、查排名、查前驱后继]

     1 const int N=1e5+5;
     2 int n,op,now,root,ans,cnt,ch[N][5];
     3 #define lc ch][0
     4 #define rc ch][1
     5 #define rnd ch][2
     6 #define sz ch][3
     7 #define v ch][4
     8 int read()
     9 {
    10     int x=0,f=1;char c=getchar();
    11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    12     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    13     return x*f;
    14 }
    15 void up(int w){w[sz]=w[lc][sz]+w[rc][sz]+1;}
    16 void dn(int w){}
    17 void split(int w,int& l,int& r,int k)
    18 {
    19     if(!w){l=r=0;return;}
    20     dn(w);int lson=w[lc][sz];
    21     if(k<=lson){r=w;split(w[lc],l,w[lc],k);}
    22     else {l=w;split(w[rc],w[rc],r,k-lson-1);}
    23     up(w);
    24 }
    25 int merge(int a,int b)
    26 {
    27     if(!a||!b)return a+b;
    28     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);up(a);return a;}
    29     else {dn(b);b[lc]=merge(a,b[lc]);up(b);return b;}
    30 }
    31 void ins(int& w,int x,int k)
    32 {
    33     dn(w);
    34     if(x[rnd]<w[rnd]||!w){split(w,x[lc],x[rc],k);w=x;up(w);return;}
    35     int lson=w[lc][sz];
    36     if(k<=lson)ins(w[lc],x,k);
    37     else ins(w[rc],x,k-lson-1);
    38     up(w);
    39 }
    40 void del(int& w,int k)
    41 {
    42     dn(w);
    43     int lson=w[lc][sz];
    44     if(k==lson+1){w=merge(w[lc],w[rc]);return;}
    45     if(k<=lson)del(w[lc],k);
    46     else del(w[rc],k-lson-1);
    47     up(w);
    48 }
    49 int rank(int w,int t)
    50 {
    51     if(!w)return 0;
    52     dn(w);
    53     if(w[v]<t){return w[lc][sz]+1+rank(w[rc],t);}
    54     else return rank(w[lc],t);
    55 }
    56 int numm(int w,int k)
    57 {
    58     dn(w);
    59     int lson=w[lc][sz];
    60     if(k==lson+1)return w[v];
    61     if(k<=lson)return numm(w[lc],k);
    62     else return numm(w[rc],k-lson-1);
    63 }
    64 void askb(int w,int t)
    65 {
    66     if(!w)return;
    67     if(w[v]<t){ans=w[v];askb(w[rc],t);}
    68     else askb(w[lc],t);
    69 }
    70 void aska(int w,int t)
    71 {
    72     if(!w)return;
    73     if(w[v]>t){ans=w[v];aska(w[lc],t);}
    74     else aska(w[rc],t);
    75 }
    View Code

      [线性建树、区间加、区间翻转、区间查询]

     1 const int N=5e4+5;
     2 int n,m,root,op,L,R,V,ans;
     3 int rt1,rt2,rt3,st[N],ch[N][8];
     4 #define lc ch][0
     5 #define rc ch][1
     6 #define rnd ch][2
     7 #define sz ch][3
     8 #define v ch][4
     9 #define tag ch][5
    10 #define rev ch][6
    11 #define mx ch][7
    12 void up(int w)
    13 {
    14     w[sz]=w[lc][sz]+w[rc][sz]+1;w[mx]=w[v];
    15     if(w[lc])w[mx]=max(w[mx],w[lc][mx]);
    16     if(w[rc])w[mx]=max(w[mx],w[rc][mx]);
    17 }
    18 void dn(int w)
    19 {
    20     if(w[tag])
    21     {
    22         w[lc][v]+=w[tag];w[lc][mx]+=w[tag];w[lc][tag]+=w[tag];
    23         w[rc][v]+=w[tag];w[rc][mx]+=w[tag];w[rc][tag]+=w[tag];
    24         w[tag]=0;
    25     }
    26     if(w[rev])
    27     {
    28         w[rev]^=1;w[lc][rev]^=1;w[rc][rev]^=1;
    29         swap(w[lc][lc],w[lc][rc]);
    30         swap(w[rc][lc],w[rc][rc]);
    31     }
    32 }
    33 void dfs(int w){if(!w)return;dfs(w[lc]);dfs(w[rc]);up(w);}
    34 int build(int n)
    35 {
    36     int top=0;
    37     for(int w=1;w<=n;w++)
    38     {
    39         w[rnd]=rand();
    40         while(top&&st[top][rnd]>w[rnd])
    41         {
    42             st[top][rc]=w[lc];
    43             w[lc]=st[top--];
    44         }
    45         st[top][rc]=w;
    46         st[++top]=w;
    47     }
    48     ch[0][1]=0;dfs(st[1]);
    49     return st[1];
    50 }
    51 void split(int w,int& l,int& r,int k)
    52 {
    53     if(!w){l=r=0;return;}
    54     dn(w);int lson=w[lc][sz];
    55     if(k<=lson){r=w;split(w[lc],l,w[lc],k);}
    56     else {l=w;split(w[rc],w[rc],r,k-lson-1);}
    57     up(w);
    58 }
    59 int merge(int a,int b)
    60 {
    61     if(!a||!b)return a+b;
    62     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);up(a);return a;}
    63     else {dn(b);b[lc]=merge(a,b[lc]);up(b);return b;}
    64 }
    65 void add(int L,int R,int V)
    66 {
    67     rt1=rt2=rt3=0;split(root,rt2,rt3,R);
    68     root=rt2;rt2=0;split(root,rt1,rt2,L-1);
    69     rt2[tag]+=V;rt2[v]+=V;rt2[mx]+=V;
    70     root=merge(rt1,rt2);root=merge(root,rt3);
    71 }
    72 void rever(int L,int R)
    73 {
    74     rt1=rt2=rt3=0;split(root,rt2,rt3,R);
    75     root=rt2;rt2=0;split(root,rt1,rt2,L-1);
    76     rt2[rev]^=1;swap(rt2[lc],rt2[rc]);
    77     root=merge(rt1,rt2);root=merge(root,rt3);
    78 }
    79 int query(int L,int R)
    80 {
    81     rt1=rt2=rt3=0;split(root,rt2,rt3,R);
    82     root=rt2;rt2=0;split(root,rt1,rt2,L-1);
    83     ans=rt2[mx];
    84     root=merge(rt1,rt2);root=merge(root,rt3);
    85     return ans;
    86 }
    View Code

      [查询历史版本]

     1 int root[N],ch[N*50][5];
     2 #define lc ch][0
     3 #define rc ch][1
     4 #define rnd ch][2
     5 #define sz ch][3
     6 #define v ch][4
     7 int copy(int w)
     8 {
     9     cnt++;cnt[lc]=w[lc];cnt[rc]=w[rc];
    10     cnt[rnd]=w[rnd];cnt[sz]=w[sz];cnt[v]=w[v];
    11     return cnt;
    12 }
    13 int newnode(int val)
    14 {
    15     cnt++;cnt[sz]=1;cnt[v]=val;
    16     cnt[rnd]=rand();return cnt;
    17 }
    18 void up(int w){w[sz]=w[lc][sz]+w[rc][sz]+1;}
    19 void dn(int w){}
    20 void split(int w,int& l,int& r,int val)
    21 {
    22     if(!w){l=r=0;return;}dn(w);
    23     if(val<w[v]){r=copy(w);split(r[lc],l,r[lc],val);up(r);}
    24     else {l=copy(w);split(l[rc],l[rc],r,val);up(l);}
    25 }
    26 int merge(int a,int b)
    27 {
    28     if(!a||!b)return a+b;
    29     if(a[rnd]<b[rnd])
    30     {
    31         dn(a);int x=copy(a);
    32         x[rc]=merge(x[rc],b);
    33         up(x);return x;
    34     }
    35     else
    36     {
    37         dn(b);int x=copy(b);
    38         x[lc]=merge(a,x[lc]);
    39         up(x);return x;
    40     }
    41 }
    42 void ins(int id,int val)
    43 {
    44     rt1=rt2=rt3=0;split(root[id],rt1,rt3,val);
    45     rt2=newnode(val);root[id]=merge(merge(rt1,rt2),rt3);
    46 }
    47 void del(int id,int val)
    48 {
    49     rt1=rt2=rt3=0;
    50     split(root[id],rt1,rt3,val);
    51     root[id]=rt1;rt1=0;
    52     split(root[id],rt1,rt2,val-1);
    53     rt2=merge(rt2[lc],rt2[rc]);
    54     root[id]=merge(merge(rt1,rt2),rt3);
    55 }
    56 int getkth(int id,int val)
    57 {
    58     rt1=rt2=0;split(root[id],rt1,rt2,val-1);
    59     int ans=rt1[sz]+1;
    60     root[id]=merge(rt1,rt2);
    61     return ans;
    62 }
    63 int getval(int w,int k)
    64 {
    65     dn(w);int lson=w[lc][sz];
    66     if(k==lson+1)return w[v];
    67     if(k<=lson)return getval(w[lc],k);
    68     else return getval(w[rc],k-lson-1);
    69 }
    70 void getpre(int w,int val)
    71 {
    72     if(!w)return;
    73     if(w[v]<val)ans=w[v],getpre(w[rc],val);
    74     else getpre(w[lc],val);
    75 }
    76 void getnext(int w,int val)
    77 {
    78     if(!w)return;
    79     if(w[v]>val)ans=w[v],getnext(w[lc],val);
    80     else getnext(w[rc],val);
    81 }
    View Code

    〖相关题目

    1.【bzoj3173】[Tjoi2013]最长上升子序列

    题意:给定一个初始为空的序列,现在将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,求此时最长上升子序列长度。

    分析:Zsnuoの博客

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdlib>
     5 using namespace std;
     6 const int N=1e5+5;
     7 int n,root,cnt,rt1,rt2,pos,ch[N][6];
     8 #define lc ch][0
     9 #define rc ch][1
    10 #define rnd ch][2
    11 #define sz ch][3
    12 #define v ch][4
    13 #define mx ch][5
    14 int read()
    15 {
    16     int x=0,f=1;char c=getchar();
    17     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    18     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    19     return x*f;
    20 }
    21 void up(int w)
    22 {
    23     w[sz]=w[lc][sz]+w[rc][sz]+1;
    24     w[mx]=max(w[lc][mx],w[rc][mx]);
    25     w[mx]=max(w[mx],w[v]);
    26 }
    27 void split(int w,int& l,int& r,int k)
    28 {
    29     if(!w){l=r=0;return;}
    30     int lson=w[lc][sz];
    31     if(k<=lson){r=w;split(w[lc],l,w[lc],k);}
    32     else {l=w;split(w[rc],w[rc],r,k-lson-1);}
    33     up(w);
    34 }
    35 int merge(int a,int b)
    36 {
    37     if(!a||!b)return a+b;
    38     if(a[rnd]<b[rnd]){a[rc]=merge(a[rc],b);up(a);return a;}
    39     else {b[lc]=merge(a,b[lc]);up(b);return b;}
    40 }
    41 void ins(int& w,int x,int k)
    42 {
    43     if(x[rnd]<w[rnd]||!w){split(w,x[lc],x[rc],k);w=x;up(w);return;}
    44     int lson=w[lc][sz];
    45     if(k<=lson)ins(w[lc],x,k);
    46     else ins(w[rc],x,k-lson-1);
    47     up(w);
    48 }
    49 int query(int pos)
    50 {
    51     rt1=rt2=0;split(root,rt1,rt2,pos);
    52     int ans=rt1[mx];root=merge(rt1,rt2);
    53     return ans;
    54 }
    55 int main()
    56 {
    57     n=read();
    58     for(int i=1;i<=n;i++)
    59     {
    60         pos=read();
    61         cnt++;cnt[v]=query(pos)+1;
    62         cnt[sz]=1;cnt[rnd]=rand();
    63         ins(root,cnt,pos);
    64         printf("%d
    ",root[mx]);
    65     }
    66     return 0;
    67 }
    View Code

    2.【SRM-07 D】天才麻将少女KPM

    题意:Zsnuoの博客

    分析:Zsnuoの博客

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<iostream>
      6 #define LL long long
      7 using namespace std;
      8 const int N=2e5+5;
      9 int n,L,R,a,tmp,cnt=1e5;
     10 int root,rt1,rt2,rt3,st[N],ch[N][9];
     11 #define lc ch][0
     12 #define rc ch][1
     13 #define rnd ch][2
     14 #define sz ch][3
     15 #define v ch][4
     16 #define tag ch][5
     17 #define mx ch][6
     18 #define mn ch][7
     19 #define cov ch][8
     20 int read()
     21 {
     22     int x=0,f=1;char c=getchar();
     23     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     24     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     25     return x*f;
     26 }
     27 void up(int w)
     28 {
     29     w[sz]=w[lc][sz]+w[rc][sz]+1;w[mx]=w[mn]=w[v];
     30     if(w[lc])w[mx]=max(w[mx],w[lc][mx]),w[mn]=min(w[mn],w[lc][mn]);
     31     if(w[rc])w[mx]=max(w[mx],w[rc][mx]),w[mn]=min(w[mn],w[rc][mn]);
     32 }
     33 void dn(int w)
     34 {
     35     if(w[cov])
     36     {
     37         w[lc][v]=w[lc][cov]=w[lc][mx]=w[lc][mn]=w[cov];
     38         w[rc][v]=w[rc][cov]=w[rc][mx]=w[rc][mn]=w[cov];
     39         w[lc][tag]=w[rc][tag]=0;
     40         w[cov]=0;
     41     }
     42     if(w[tag])
     43     {
     44         w[lc][v]+=w[tag];w[lc][tag]+=w[tag];
     45         w[lc][mx]+=w[tag];w[lc][mn]+=w[tag];
     46         w[rc][v]+=w[tag];w[rc][tag]+=w[tag];
     47         w[rc][mx]+=w[tag];w[rc][mn]+=w[tag];
     48         w[tag]=0;
     49     }
     50 }
     51 void dfs(int w){if(!w)return;dfs(w[lc]);dfs(w[rc]);up(w);}
     52 int build()
     53 {
     54     int top=0;
     55     for(int w=1;w<=1e5;w++)
     56     {
     57         w[rnd]=rand();
     58         while(top&&st[top][rnd]>w[rnd])
     59         {
     60             st[top][rc]=w[lc];
     61             w[lc]=st[top--];
     62         }
     63         st[top][rc]=w;st[++top]=w;
     64     }
     65     ch[0][1]=0;dfs(st[1]);
     66     return st[1];
     67 }
     68 void split(int w,int& l,int& r,int k)
     69 {
     70     if(!w){l=r=0;return;}
     71     dn(w);int lson=w[lc][sz];
     72     if(k<=lson){r=w;split(w[lc],l,w[lc],k);}
     73     else{l=w;split(w[rc],w[rc],r,k-lson-1);}
     74     up(w);
     75 }
     76 int merge(int a,int b)
     77 {
     78     if(!a||!b)return a+b;
     79     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);up(a);return a;}
     80     else{dn(b);b[lc]=merge(a,b[lc]);up(b);return b;}
     81 }
     82 int rank(int w,int k)
     83 {
     84     if(!w)return 0;dn(w);
     85     int lson=w[lc][sz];
     86     if(k==lson+1)return w[v];
     87     if(k<=lson)return rank(w[lc],k);
     88     else return rank(w[rc],k-lson-1);
     89 }
     90 void ins(int& w,int x,int k)
     91 {
     92     dn(w);
     93     if(x[rnd]<w[rnd]||!w){split(w,x[lc],x[rc],k);w=x;up(w);return;}
     94     int lson=w[lc][sz];
     95     if(k<=lson)ins(w[lc],x,k);
     96     else ins(w[rc],x,k-lson-1);
     97     up(w);
     98 }
     99 void del(int& w,int k)
    100 {
    101     dn(w);
    102     int lson=w[lc][sz];
    103     if(k==lson+1){w=merge(w[lc],w[rc]);return;}
    104     if(k<=lson)del(w[lc],k);
    105     else del(w[rc],k-lson-1);
    106     up(w);
    107 }
    108 void add(int L,int R,int V)
    109 {
    110     rt1=rt2=rt3=0;split(root,rt2,rt3,R);
    111     root=rt2;rt2=0;split(root,rt1,rt2,L-1);
    112     rt2[tag]+=V;rt2[v]+=V;rt2[mx]+=V;rt2[mn]+=V;
    113     root=merge(rt1,rt2);root=merge(root,rt3);
    114 }
    115 void cover(int w,int V)
    116 {
    117     if(!w||w[mn]>=V)return;
    118     dn(w);if(w[v]<V)w[v]=V;
    119     if(w[mx]<=V){w[cov]=V;w[tag]=0;up(w);return;}
    120     cover(w[lc],V);cover(w[rc],V);
    121     up(w);
    122 }
    123 void update(int L,int R,int V)
    124 {
    125     rt1=rt2=rt3=0;split(root,rt2,rt3,R);
    126     root=rt2;rt2=0;split(root,rt1,rt2,L-1);
    127     cover(rt2,V);
    128     root=merge(rt1,rt2);root=merge(root,rt3);
    129 }
    130 int main()
    131 {
    132     n=read();L=read();R=read();root=build();
    133     for(int i=1;i<=n;i++)
    134     {
    135         a=read();
    136         if(a>0)
    137         {
    138             tmp=rank(root,a-1)+1;
    139             update(a,1e5,tmp);
    140         }
    141         else
    142         {
    143             del(root,R);cnt++;
    144             tmp=rank(root,L-1);
    145             cnt[v]=tmp;cnt[rnd]=rand();
    146             ins(root,cnt,L-1);
    147             add(L,R,1);tmp=rank(root,R);
    148             if(R!=1e5)update(R+1,1e5,tmp);
    149         }
    150     }
    151     printf("%d",root[mx]);
    152     return 0;
    153 }
    View Code

    3.【bzoj3786】星系探索

    题意:见原题

    分析:Zsnuoの博客

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #define LL long long
      6 using namespace std;
      7 const int N=2e5+10;
      8 int n,m,cnt,tmp,x,y,root,rt1,rt2,rt3;
      9 int st[N],q[N],first[N],ch[N][7];
     10 LL sh[N][3];
     11 char op[2];
     12 struct edge{int to,next;}e[N];
     13 #define lc ch][0
     14 #define rc ch][1
     15 #define rnd ch][2
     16 #define sz ch][3
     17 #define xi ch][4
     18 #define num ch][5
     19 #define fa ch][6
     20 #define v sh][0
     21 #define sum sh][1
     22 #define tag sh][2
     23 int read()
     24 {
     25     int x=0,f=1;char c=getchar();
     26     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     27     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     28     return x*f;
     29 }
     30 void ins(int from,int to){e[++cnt]=(edge){to,first[from]};first[from]=cnt;}
     31 void dfs(int x)
     32 {
     33     q[++cnt]=x;
     34     for(int i=first[x];i;i=e[i].next)dfs(e[i].to);
     35     q[++cnt]=x+n;
     36 }
     37 void up(int w)
     38 {
     39     int l=w[lc],r=w[rc];
     40     w[sz]=l[sz]+r[sz]+1;
     41     w[num]=l[num]+r[num]+w[xi];
     42     w[sum]=l[sum]+r[sum]+w[v];
     43 }
     44 void dn(int w)
     45 {
     46     int l=w[lc],r=w[rc];LL t=w[tag];
     47     if(!t)return;w[tag]=0;
     48     if(l)l[tag]+=t,l[v]+=t*l[xi],l[sum]+=t*l[num];
     49     if(r)r[tag]+=t,r[v]+=t*r[xi],r[sum]+=t*r[num];
     50 //    printf("l:%d xi:%d r:%d xi:%d
    ",l,l[xi],r,r[xi]);
     51 }
     52 void check(int w){if(!w)return;check(w[lc]);check(w[rc]);up(w);}
     53 int build(int n)
     54 {
     55     int top=0,w;
     56     for(int i=1;i<=n;i++)
     57     {
     58         w=q[i];w[rnd]=rand();
     59         while(top&&st[top][rnd]>w[rnd])
     60         {
     61             w[lc][fa]=st[top];st[top][rc]=w[lc];
     62             st[top][fa]=w;w[lc]=st[top--];
     63         }
     64         w[fa]=st[top];st[top][rc]=w;st[++top]=w;
     65     }
     66     ch[0][1]=0;st[1][fa]=0;check(st[1]);
     67     return st[1];
     68 }
     69 void split(int w,int& l,int fal,int& r,int far,int k)
     70 {
     71     if(!w){l=r=0;return;}
     72     dn(w);int lson=w[lc][sz];
     73     if(k<=lson)w[fa]=far,r=w,split(w[lc],l,fal,w[lc],w,k);
     74     else w[fa]=fal,l=w,split(w[rc],w[rc],w,r,far,k-lson-1);
     75     up(w);
     76 }
     77 int merge(int a,int b)
     78 {
     79     if(!a||!b)return a+b;
     80     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);a[rc][fa]=a;up(a);return a;}
     81     else {dn(b);b[lc]=merge(a,b[lc]);b[lc][fa]=b;up(b);return b;}
     82 }
     83 int find(int x)
     84 {
     85     int ans=x[lc][sz]+1;
     86     while(x[fa])
     87     {
     88         if(x[fa][rc]==x)ans+=x[fa][lc][sz]+1;
     89         x=x[fa];
     90     }
     91     return ans;
     92 }
     93 void query()
     94 {
     95     x=read();rt1=rt2=0;split(root,rt1,0,rt2,0,find(x));
     96     printf("%lld
    ",rt1[sum]);root=merge(rt1,rt2);
     97 }
     98 void change()
     99 {
    100     x=read();y=read();rt1=rt2=rt3=0;
    101     split(root,rt1,0,rt3,0,find(x+n));
    102     root=rt1;rt1=0;split(root,rt1,0,rt2,0,find(x)-1);
    103     root=merge(rt1,rt3);rt1=rt3=0;
    104     split(root,rt1,0,rt3,0,find(y));
    105     root=merge(rt1,rt2);root=merge(root,rt3);
    106 }
    107 void add()
    108 {
    109     x=read();y=read();rt1=rt2=rt3=0;
    110     split(root,rt1,0,rt3,0,find(x+n));
    111     root=rt1;rt1=0;split(root,rt1,0,rt2,0,find(x)-1);
    112     int w=rt2;w[tag]+=y;w[v]+=y*w[xi];w[sum]+=1ll*y*w[num];
    113     root=merge(rt1,rt2);root=merge(root,rt3);
    114 }
    115 void print(int w,int dir)
    116 {
    117     if(!w)return;
    118     if(dir==0)printf("from-left ");
    119     if(dir==1)printf("from-right ");
    120     printf("[%d] fa:%d v:%lld sum:%lld lson:%d rson:%d
    ",w,w[fa],w[v],w[sum],w[lc],w[rc]);
    121     print(w[lc],0);print(w[rc],1);
    122 }
    123 int main()
    124 {
    125     n=read();
    126     for(int i=2;i<=n;i++)tmp=read(),ins(tmp,i);
    127     for(int i=1;i<=n;i++)tmp=read(),i[v]=tmp,(i+n)[v]=-tmp,i[xi]=1,(i+n)[xi]=-1;
    128     cnt=0;dfs(1);root=build(n*2);m=read();//print(root,-1);
    129     while(m--)
    130     {
    131         scanf("%s",op+1);
    132         if(op[1]=='Q')query();
    133         else if(op[1]=='C')change();
    134         else add();
    135 //        print(root,-1);
    136     }
    137     return 0;
    138 }
    View Code
      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #define LL long long
      6 using namespace std;
      7 const int N=2e5+10;
      8 int n,m,cnt,tmp,x,y,root,rt1,rt2,rt3;
      9 int st[N],q[N],first[N],ch[N][7];
     10 LL sh[N][3];
     11 char op[2];
     12 struct edge{int to,next;}e[N];
     13 #define lc ch][0
     14 #define rc ch][1
     15 #define rnd ch][2
     16 #define sz ch][3
     17 #define xi ch][4
     18 #define num ch][5
     19 #define fa ch][6
     20 #define v sh][0
     21 #define sum sh][1
     22 #define tag sh][2
     23 int read()
     24 {
     25     int x=0,f=1;char c=getchar();
     26     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     27     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     28     return x*f;
     29 }
     30 void ins(int from,int to){e[++cnt]=(edge){to,first[from]};first[from]=cnt;}
     31 void dfs(int x)
     32 {
     33     q[++cnt]=x;
     34     for(int i=first[x];i;i=e[i].next)dfs(e[i].to);
     35     q[++cnt]=x+n;
     36 }
     37 void up(int w)
     38 {
     39     int l=w[lc],r=w[rc];
     40     w[sz]=l[sz]+r[sz]+1;
     41     w[num]=l[num]+r[num]+w[xi];
     42     w[sum]=l[sum]+r[sum]+w[v];
     43     if(l)l[fa]=w;if(r)r[fa]=w;
     44 }
     45 void dn(int w)
     46 {
     47     int l=w[lc],r=w[rc];LL t=w[tag];
     48     if(!t)return;w[tag]=0;
     49     if(l)l[tag]+=t,l[v]+=t*l[xi],l[sum]+=t*l[num];
     50     if(r)r[tag]+=t,r[v]+=t*r[xi],r[sum]+=t*r[num];
     51 }
     52 void check(int w){if(!w)return;check(w[lc]);check(w[rc]);up(w);}
     53 int build(int n)
     54 {
     55     int top=0,w;
     56     for(int i=1;i<=n;i++)
     57     {
     58         w=q[i];w[rnd]=rand();
     59         while(top&&st[top][rnd]>w[rnd])st[top][rc]=w[lc],w[lc]=st[top--];
     60         st[top][rc]=w;st[++top]=w;
     61     }
     62     ch[0][1]=0;st[1][fa]=0;check(st[1]);
     63     return st[1];
     64 }
     65 void split(int w,int& l,int fal,int& r,int far,int k)
     66 {
     67     if(!w){l=r=0;return;}
     68     dn(w);int lson=w[lc][sz];
     69     if(k<=lson)r=w,split(w[lc],l,fal,w[lc],w,k);
     70     else l=w,split(w[rc],w[rc],w,r,far,k-lson-1);
     71     up(w);
     72 }
     73 int merge(int a,int b)
     74 {
     75     if(!a||!b)return a+b;
     76     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);up(a);return a;}
     77     else {dn(b);b[lc]=merge(a,b[lc]);up(b);return b;}
     78 }
     79 int find(int x)
     80 {
     81     int ans=x[lc][sz]+1;
     82     while(x[fa])
     83     {
     84         if(x[fa][rc]==x)ans+=x[fa][lc][sz]+1;
     85         x=x[fa];
     86     }
     87     return ans;
     88 }
     89 void query()
     90 {
     91     x=read();rt1=rt2=0;split(root,rt1,0,rt2,0,find(x));
     92     rt1[fa]=rt2[fa]=0;printf("%lld
    ",rt1[sum]);root=merge(rt1,rt2);root[fa]=0;
     93 }
     94 void change()
     95 {
     96     x=read();y=read();rt1=rt2=rt3=0;
     97     split(root,rt1,0,rt3,0,find(x+n));
     98     rt1[fa]=rt3[fa]=0;root=rt1;rt1=0;
     99     split(root,rt1,0,rt2,0,find(x)-1);
    100     rt1[fa]=rt2[fa]=0;root=merge(rt1,rt3);rt1=rt3=0;
    101     split(root,rt1,0,rt3,0,find(y));
    102     root=merge(rt1,rt2);root=merge(root,rt3);root[fa]=0;
    103 }
    104 void add()
    105 {
    106     x=read();y=read();rt1=rt2=rt3=0;
    107     split(root,rt1,0,rt3,0,find(x+n));
    108     rt1[fa]=rt3[fa]=0;root=rt1;rt1=0;
    109     split(root,rt1,0,rt2,0,find(x)-1);rt1[fa]=rt2[fa]=0;
    110     int w=rt2;w[tag]+=y;w[v]+=y*w[xi];w[sum]+=1ll*y*w[num];
    111     root=merge(rt1,rt2);root=merge(root,rt3);root[fa]=0;
    112 }
    113 int main()
    114 {
    115     n=read();
    116     for(int i=2;i<=n;i++)tmp=read(),ins(tmp,i);
    117     for(int i=1;i<=n;i++)tmp=read(),i[v]=tmp,(i+n)[v]=-tmp,i[xi]=1,(i+n)[xi]=-1;
    118     cnt=0;dfs(1);
    119     root=build(n*2);m=read();
    120     while(m--)
    121     {
    122         scanf("%s",op+1);
    123         if(op[1]=='Q')query();
    124         else if(op[1]=='C')change();
    125         else add();
    126     }
    127     return 0;
    128 }
    View Code

    4.【bzoj1500】[NOI2005]维修数列

    题意:见原题

    分析:Zsnuoの博客

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdlib>
      5 using namespace std;
      6 const int N=5e5+5;
      7 const int inf=0x3f3f3f3f;
      8 int n,m,tot,pos,val,cnt,root,rt1,rt2,rt3;
      9 int st[N],id[N],a[N],ch[N][11];
     10 char op[15];
     11 #define lc ch][0
     12 #define rc ch][1
     13 #define rnd ch][2
     14 #define sz ch][3
     15 #define v ch][4
     16 #define tag ch][5
     17 #define rev ch][6
     18 #define sum ch][7
     19 #define mx ch][8
     20 #define lsum ch][9
     21 #define rsum ch][10
     22 int read()
     23 {
     24     int x=0,f=1;char c=getchar();
     25     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     26     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     27     return x*f;
     28 }
     29 int max(int a,int b){return a>b?a:b;}
     30 void up(int w)
     31 {
     32     int l=w[lc],r=w[rc];
     33     w[sz]=l[sz]+r[sz]+1;
     34     w[sum]=l[sum]+r[sum]+w[v];
     35     w[mx]=l[rsum]+w[v]+r[lsum];
     36     if(l)w[mx]=max(w[mx],l[mx]);
     37     if(r)w[mx]=max(w[mx],r[mx]);
     38     w[lsum]=max(l[lsum],l[sum]+w[v]+r[lsum]);
     39     w[rsum]=max(r[rsum],r[sum]+w[v]+l[rsum]);
     40 }
     41 void dn(int w)
     42 {
     43     int l=w[lc],r=w[rc];
     44     if(w[tag])
     45     {
     46         w[rev]=w[tag]=0;
     47         if(l)l[tag]=1,l[v]=w[v],l[sum]=w[v]*l[sz];
     48         if(r)r[tag]=1,r[v]=w[v],r[sum]=w[v]*r[sz];
     49         if(w[v]>=0)
     50         {
     51             if(l)l[mx]=l[lsum]=l[rsum]=l[sum];
     52             if(r)r[mx]=r[lsum]=r[rsum]=r[sum];
     53         }
     54         else
     55         {
     56             if(l)l[lsum]=l[rsum]=0,l[mx]=w[v];
     57             if(r)r[lsum]=r[rsum]=0,r[mx]=w[v];
     58         }
     59     }
     60     if(w[rev])
     61     {
     62         w[rev]^=1;l[rev]^=1;r[rev]^=1;
     63         swap(l[lsum],l[rsum]);swap(r[lsum],r[rsum]);
     64         swap(l[lc],l[rc]);swap(r[lc],r[rc]);
     65     }
     66 }
     67 void dfs(int w){if(!w)return;dfs(w[lc]);dfs(w[rc]);up(w);}
     68 int build(int n)
     69 {
     70     int top=0,w;
     71     for(int i=1;i<=n;i++)
     72     {
     73         w=id[cnt--];
     74         w[rnd]=rand();w[v]=a[i];
     75         while(top&&st[top][rnd]>w[rnd])
     76         {
     77             st[top][rc]=w[lc];
     78             w[lc]=st[top--];
     79         }
     80         st[top][rc]=w;
     81         st[++top]=w;
     82     }
     83     ch[0][1]=0;dfs(st[1]);
     84     return st[1];
     85 }
     86 void split(int w,int& l,int& r,int k)
     87 {
     88     if(!w){l=r=0;return;}
     89     dn(w);int lson=w[lc][sz];
     90     if(k<=lson){r=w;split(w[lc],l,w[lc],k);}
     91     else {l=w;split(w[rc],w[rc],r,k-lson-1);}
     92     up(w);
     93 }
     94 int merge(int a,int b)
     95 {
     96     if(!a||!b)return a+b;
     97     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);up(a);return a;}
     98     else {dn(b);b[lc]=merge(a,b[lc]);up(b);return b;}
     99 }
    100 void insert(int pos,int tot)
    101 {
    102     for(int i=1;i<=tot;i++)a[i]=read();
    103     rt1=rt2=rt3=0;split(root,rt1,rt3,pos);
    104     rt2=build(tot);
    105     root=merge(rt1,rt2);root=merge(root,rt3);
    106 }
    107 void rec(int w)
    108 {
    109     if(!w)return;
    110     int l=w[lc],r=w[rc];
    111     rec(l);rec(r);id[++cnt]=w;
    112     memset(ch[w],0,sizeof(ch[w]));
    113 }
    114 void erase(int pos,int tot)
    115 {
    116     rt1=rt2=rt3=0;split(root,rt2,rt3,pos+tot-1);
    117     root=rt2;rt2=0;split(root,rt1,rt2,pos-1);
    118     rec(rt2);root=merge(rt1,rt3);
    119 }
    120 void makesame(int pos,int tot,int val)
    121 {
    122     rt1=rt2=rt3=0;split(root,rt2,rt3,pos+tot-1);
    123     root=rt2;rt2=0;split(root,rt1,rt2,pos-1);
    124     int w=rt2;w[tag]=1;w[v]=val;w[sum]=val*w[sz];
    125     if(val>=0)w[lsum]=w[rsum]=w[mx]=w[sum];
    126     else w[lsum]=w[rsum]=0,w[mx]=val;
    127     root=merge(rt1,rt2);root=merge(root,rt3);
    128 }
    129 void rever(int pos,int tot)
    130 {
    131     rt1=rt2=rt3=0;split(root,rt2,rt3,pos+tot-1);
    132     root=rt2;rt2=0;split(root,rt1,rt2,pos-1);
    133     int w=rt2;w[rev]^=1;swap(w[lc],w[rc]);swap(w[lsum],w[rsum]);
    134     root=merge(rt1,rt2);root=merge(root,rt3);
    135 }
    136 void query(int pos,int tot)
    137 {
    138     rt1=rt2=rt3=0;split(root,rt2,rt3,pos+tot-1);
    139     root=rt2;rt2=0;split(root,rt1,rt2,pos-1);
    140     printf("%d
    ",rt2[sum]);root=merge(rt1,rt2);root=merge(root,rt3);
    141 }
    142 int main()
    143 {
    144     n=read();m=read();cnt=N-5;
    145     for(int i=1;i<=N-5;i++)id[i]=i;
    146     for(int i=1;i<=n;i++)a[i]=read();
    147     root=build(n);
    148     while(m--)
    149     {
    150         scanf("%s",op);
    151         if(op[0]!='M'||op[2]!='X')pos=read(),tot=read();
    152         if(op[0]=='I')insert(pos,tot);
    153         else if(op[0]=='D')erase(pos,tot);
    154         else if(op[0]=='M')
    155         {
    156             if(op[2]=='X')printf("%d
    ",root[mx]);
    157             else val=read(),makesame(pos,tot,val);
    158         }
    159         else if(op[0]=='R')rever(pos,tot);
    160         else query(pos,tot);
    161     }
    162     return 0;
    163 }
    View Code

    【CDQ分治】

    〖相关资料

    《从《Cash》谈一类分治算法的应用》

    〖相关题目

    1.【bzoj1492】[NOI2007]货币兑换Cash

    题意:见原题

    分析:见资料

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 using namespace std;
     6 const int N=1e5+5;
     7 const double eps=1e-9;
     8 int n,s[N];
     9 double f[N];
    10 struct node{double x,y,a,b,k,rate;int id;}t[N],tmp[N];
    11 bool cmp(node a,node b){return a.k>b.k;}
    12 double get(int a,int b)
    13 {
    14     if(!b)return -1e30;
    15     if(fabs(t[a].x-t[b].x)<eps)return 1e30;
    16     return (t[b].y-t[a].y)/(t[b].x-t[a].x);
    17 }
    18 void cdq(int l,int r)
    19 {
    20     if(l==r)
    21     {
    22         f[l]=max(f[l],f[l-1]);
    23         t[l].y=f[l]/(t[l].a*t[l].rate+t[l].b);
    24         t[l].x=t[l].y*t[l].rate;
    25         return;
    26     }
    27     int mid=(l+r)>>1,h1=l,h2=mid+1;
    28     for(int i=l;i<=r;i++)
    29         if(t[i].id<=mid)tmp[h1++]=t[i];
    30         else tmp[h2++]=t[i];
    31     for(int i=l;i<=r;i++)t[i]=tmp[i];
    32     cdq(l,mid);int top=0,now=1;
    33     for(int i=l;i<=mid;i++)
    34     {
    35         while(top>1&&get(s[top-1],s[top])<get(s[top],i)+eps)top--;
    36         s[++top]=i;
    37     }
    38     s[++top]=0;
    39     for(int i=mid+1;i<=r;i++)
    40     {
    41         while(get(s[now],s[now+1])+eps>t[i].k)now++;
    42         f[t[i].id]=max(f[t[i].id],t[s[now]].x*t[i].a+t[s[now]].y*t[i].b);
    43     }
    44     cdq(mid+1,r);h1=l;h2=mid+1;
    45     for(int i=l;i<=r;i++)
    46     {
    47         if(h1>mid){tmp[i]=t[h2++];continue;}
    48         if(h2>r){tmp[i]=t[h1++];continue;}
    49         if(t[h1].x<t[h2].x||(fabs(t[h1].x-t[h2].x)<eps&&t[h1].y<t[h2].y))tmp[i]=t[h1++];
    50         else tmp[i]=t[h2++];
    51     }
    52     for(int i=l;i<=r;i++)t[i]=tmp[i];
    53 }
    54 int main()
    55 {
    56     scanf("%d%lf",&n,&f[0]);
    57     for(int i=1;i<=n;i++)
    58     {
    59         scanf("%lf%lf%lf",&t[i].a,&t[i].b,&t[i].rate);
    60         t[i].k=-t[i].a/t[i].b;t[i].id=i;
    61     }
    62     sort(t+1,t+n+1,cmp);cdq(1,n);
    63     printf("%.3lf",f[n]);
    64     return 0;
    65 }
    View Code

    【整体二分】

    〖相关题目

    1.【bzoj1901】Zju2112 Dynamic Rankings

    题意:给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。

    分析:带修改的整体二分

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define LL long long
     5 using namespace std;
     6 const int N=5e4+5;
     7 const int inf=1e9;
     8 int n,m,cnt,qid,id,temp,x[N],ans[N],tr[N];
     9 bool f[N];
    10 char ch[5];
    11 struct node{int op,l,r,k,num;}a[N],tmp[N];
    12 int lowbit(int x){return x&(-x);}
    13 void insert(int x,int c){while(x<=n)tr[x]+=c,x+=lowbit(x);}
    14 int query(int x){int ans=0;while(x)ans+=tr[x],x-=lowbit(x);return ans;}
    15 int read()
    16 {
    17     int x=0,f=1;char c=getchar();
    18     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    19     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    20     return x*f;
    21 }
    22 void work(int ql,int qr,int L,int R)
    23 {
    24     if(ql>qr||L>R)return;
    25     if(L==R){for(int i=ql;i<=qr;i++)if(a[i].op)ans[a[i].num]=L;return;}
    26     int mid=(L+R)>>1,h1=ql,h2=ql;
    27     for(int i=ql;i<=qr;i++)
    28         if(a[i].op)
    29         {
    30             temp=query(a[i].r)-query(a[i].l-1);
    31             if(temp>=a[i].k)f[i]=true,h2++;
    32             else f[i]=false,a[i].k-=temp;
    33         }
    34         else
    35         {
    36             if(a[i].num<=mid)f[i]=true,h2++,insert(a[i].l,a[i].k);
    37             else f[i]=false;
    38         }
    39     for(int i=ql;i<=qr;i++)if((!a[i].op)&&f[i])insert(a[i].l,-a[i].k);
    40     for(int i=ql;i<=qr;i++)
    41         if(f[i])tmp[h1++]=a[i];
    42         else tmp[h2++]=a[i];
    43     for(int i=ql;i<=qr;i++)a[i]=tmp[i];
    44     work(ql,h1-1,L,mid);work(h1,qr,mid+1,R);
    45 }
    46 int main()
    47 {
    48     n=read();m=read();
    49     for(int i=1;i<=n;i++)x[i]=read(),a[++cnt]=(node){0,i,0,1,x[i]};
    50     for(int i=1;i<=m;i++)
    51     {
    52         scanf("%s",ch+1);
    53         if(ch[1]=='Q')
    54         {
    55             a[++cnt].op=1;a[cnt].num=++qid;
    56             a[cnt].l=read();a[cnt].r=read();a[cnt].k=read();
    57         }
    58         else
    59         {
    60             id=read();temp=read();
    61             a[++cnt]=(node){0,id,0,-1,x[id]};
    62             a[++cnt]=(node){0,id,0,1,x[id]=temp};
    63         }
    64     }
    65     work(1,cnt,-inf,inf);
    66     for(int i=1;i<=qid;i++)printf("%d
    ",ans[i]);
    67     return 0;
    68 }
    View Code

    2.【bzoj2527】[Poi2011]Meteors

    题意:见原题

    分析:Zsnuoの博客 

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #define LL long long
     6 using namespace std;
     7 const int N=3e5+5;
     8 const int inf=0x3f3f3f3f;
     9 int n,m,K,now,op;
    10 int num[N],Li[N],Ri[N],Ai[N],id[N],tmp[N],ans[N];
    11 LL sum,tr[N];
    12 bool f[N];
    13 vector<int> nation[N];
    14 int read()
    15 {
    16     int x=0,f=1;char c=getchar();
    17     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    18     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    19     return x*f;
    20 }
    21 int lowbit(int x){return x&(-x);}
    22 void add(int x,LL c){while(x<=m)tr[x]+=c,x+=lowbit(x);}
    23 LL query(int x){LL ans=0;while(x)ans+=tr[x],x-=lowbit(x);return ans;}
    24 void update(int id,int f)
    25 {
    26     if(Li[id]<=Ri[id])add(Li[id],Ai[id]*f),add(Ri[id]+1,-Ai[id]*f);
    27     else add(1,Ai[id]*f),add(Ri[id]+1,-Ai[id]*f),add(Li[id],Ai[id]*f);
    28 }
    29 void work(int ql,int qr,int L,int R)
    30 {
    31     if(ql>qr)return;
    32     if(L==R){for(int i=ql;i<=qr;i++)ans[id[i]]=L;return;}
    33     int h1=ql,h2=ql,mid=(L+R)>>1;
    34     while(op<mid)op++,update(op,1);
    35     while(op>mid)update(op,-1),op--;
    36     for(int i=ql;i<=qr;i++)
    37     {
    38         sum=0;now=id[i];
    39         for(int j=0;j<nation[now].size();j++)
    40         {
    41             sum+=query(nation[now][j]);
    42             if(sum>=num[now])break;
    43         }
    44         if(sum>=num[now])f[now]=true,h2++;
    45         else f[now]=false;
    46     }
    47     for(int i=ql;i<=qr;i++)
    48         if(f[id[i]])tmp[h1++]=id[i];
    49         else tmp[h2++]=id[i];
    50     for(int i=ql;i<=qr;i++)id[i]=tmp[i];
    51     work(ql,h1-1,L,mid);work(h1,qr,mid+1,R);
    52 }
    53 int main()
    54 {
    55     n=read();m=read();
    56     for(int i=1;i<=m;i++)now=read(),nation[now].push_back(i);
    57     for(int i=1;i<=n;i++)num[i]=read(),id[i]=i;
    58     K=read();K++;Li[K]=1;Ri[K]=m;Ai[K]=inf;
    59     for(int i=1;i<K;i++)Li[i]=read(),Ri[i]=read(),Ai[i]=read();
    60     work(1,n,1,K);
    61     for(int i=1;i<=n;i++)
    62         if(ans[i]==K)printf("NIE
    ");
    63         else printf("%d
    ",ans[i]);
    64     return 0;
    65 }
    View Code

    3.【bzoj3110】[Zjoi2013]K大数查询

    题意:有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c。如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

    分析:整体二分裸题

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #define LL long long
     6 using namespace std;
     7 const int N=1e5+5;
     8 int n,m,qid,mx,ans[N];
     9 LL tr[N][2];
    10 bool f[N];
    11 struct node{int op,l,r,c,id;}a[N],tmp[N];
    12 LL read()
    13 {
    14     LL x=0,f=1;char c=getchar();
    15     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    16     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    17     return x*f;
    18 }
    19 int lowbit(int x){return x&(-x);}
    20 void add(int x,LL c,int id){while(x<=n)tr[x][id]+=c,x+=lowbit(x);}
    21 void insert(int id,LL c){add(id,c,0);add(id,c*id,1);}
    22 LL query(int x,int id){LL ans=0;while(x)ans+=tr[x][id],x-=lowbit(x);return ans;}
    23 LL ask(int id){LL ans=(id+1)*query(id,0)-query(id,1);return ans;}
    24 void work(int x,int y,int l,int r)
    25 {
    26     if(l==r){for(int i=x;i<=y;i++)if(a[i].op==2)ans[a[i].id]=l;return;}
    27     int h1=x,h2=x,mid=(l+r)>>1;
    28     for(int i=x;i<=y;i++)
    29         if(a[i].op==2)
    30         {
    31             LL temp=ask(a[i].r)-ask(a[i].l-1);
    32             if(temp<a[i].c)f[i]=false,a[i].c-=temp;
    33             else f[i]=true,h2++;
    34         }
    35         else if(a[i].c<=mid)insert(a[i].l,1),insert(a[i].r+1,-1),f[i]=true,h2++;
    36         else f[i]=false;
    37     for(int i=x;i<=y;i++)if(a[i].op==1&&a[i].c<=mid)insert(a[i].l,-1),insert(a[i].r+1,1);
    38     for(int i=x;i<=y;i++)if(f[i])tmp[h1++]=a[i];else tmp[h2++]=a[i];
    39     for(int i=x;i<=y;i++)a[i]=tmp[i];
    40     work(x,h1-1,l,mid);work(h1,y,mid+1,r);
    41 }
    42 int main()
    43 {
    44     n=read();m=read();
    45     for(int i=1;i<=m;i++)
    46     {
    47         a[i].op=read();a[i].l=read();a[i].r=read();a[i].c=read();
    48         if(a[i].op==1)a[i].c=n-a[i].c+1,mx=max(mx,a[i].c);
    49         else a[i].id=++qid;
    50     }
    51     work(1,m,1,mx);
    52     for(int i=1;i<=qid;i++)printf("%d
    ",n-ans[i]+1);
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    git submodule的使用
    Git 工具
    Simple Rtmp Server的安装与简单使用
    Java 获取当前系统的操作系统类型
    OA系统 权限管理的设计流程
    基于角色访问控制的OA系统的设计与实现
    Neo4j:Index索引
    Neo4j Cypher查询语言详解
    win10命令行kill进程
    用BlazeMeter录制JMeter测试脚本
  • 原文地址:https://www.cnblogs.com/zsnuo/p/8886317.html
Copyright © 2011-2022 走看看