• HNCU专题训练_线段树(1)


    1.内存控制
    2.敌兵布阵
    4.广告牌
    5.区间第k大数(模板题)
    6.just a Hook
    7.I Hate It
    8.动态的最长递增子序列(区间更新题)
    9.图灵树
    10.覆盖的面积
    14.买票问题
    16.村庄问题
    17.Hotel
    19.矩形周长问题
    23.区间第k大数问题
    26.海报问题

    1001

      1 /*
      2 
      3 内存控制
      4 4种操作:
      5 1.Reset 初始化
      6 2.New x 开辟长度为x的连续的空间,输出起始位置
      7 3.Free x 释放包含第x字节的块,整块都释放掉
      8 4.Get x  输出当前状态下,内存里第x块的起始位置
      9 
     10 思路:
     11 1.Reset 很简单,update(1,N,EMPTY,1);就可以了
     12         没有必要重新构树
     13 
     14 2.New  x 对于这个操作,和Hotel这道题是一样的。
     15         建立树的过程中保存了lmax,rmax,max。在查询的
     16         过程中有一些小的技巧。
     17 
     18 3.Free x 释放内存,开一个容器,维护这个容器的顺序。
     19         学到了很多容器的知识。海,以前没有学过容器
     20         还是学别人的。
     21 4.Get x 也是通过维护这个容器,来得到的。
     22 
     23 详细的见代码
     24 
     25 
     26 */
     27 
     28 #include<cstdio>
     29 #include<iostream>
     30 #include<cstdlib>
     31 #include<algorithm>
     32 #include<vector>
     33 #define EMPTY 2 //纯色  此题中代表  空的。
     34 #define HH 1 //混色  此题中代表 被占用了。
     35 using namespace std;
     36 
     37 
     38 
     39 struct node
     40 {
     41     int l;
     42     int r;
     43     int lmax,rmax,max;
     44     int len;
     45     int color;
     46 }f[50003*4];
     47 struct st
     48 {
     49     int begin;
     50     int end;
     51 };
     52 vector<st>tom;
     53 
     54 
     55 int hmax(int x,int y)
     56 {
     57     return x>y? x:y;
     58 }
     59 
     60 bool cmp1(st n1,st n2)
     61 {
     62     return n1.begin<n2.begin;
     63 }
     64 
     65 void build(int l,int r,int n) //建树。
     66 {
     67     int mid=(l+r)/2;
     68     f[n].l=l;
     69     f[n].r=r;
     70     f[n].color=0;
     71     f[n].len=f[n].r-f[n].l+1;
     72     f[n].lmax=f[n].rmax=f[n].max=f[n].len;
     73     if(l==r)
     74     return;
     75     build(l,mid,n*2);
     76     build(mid+1,r,n*2+1);
     77 }
     78 /*
     79 建设的过程也有一个小小的亮点,可以把
     80  f[n].lmax=f[n].rmax=f[n].max=f[n].len;
     81  用向上更新来写在build(mid+1,r,n*2+1)后,带上
     82 */
     83 
     84 void make_down(int n) //向下更新
     85 {
     86     if(f[n].color==EMPTY)
     87     {
     88         f[n*2].max=f[n*2].rmax=f[n*2].lmax=f[n*2].len;
     89         f[n*2+1].max=f[n*2+1].rmax=f[n*2+1].lmax=f[n*2+1].len;
     90     }
     91     else if(f[n].color==HH)
     92     {
     93         f[n*2].max=f[n*2].lmax=f[n*2].rmax=0;
     94         f[n*2+1].max=f[n*2+1].lmax=f[n*2+1].rmax=0;
     95     }
     96 
     97     f[n*2].color=f[n].color;
     98     f[n*2+1].color=f[n].color;
     99 
    100     f[n].color=0;
    101     f[n].lmax=f[n].rmax=f[n].max=0;
    102 
    103 }
    104 
    105 void make_up(node *father,node *l_child,node *r_child) //向上更新
    106 {
    107     father->lmax=(l_child->lmax==l_child->len)? l_child->lmax+r_child->lmax: l_child->lmax;
    108     father->rmax=(r_child->rmax==r_child->len)? r_child->rmax+l_child->rmax: r_child->rmax;
    109     father->max=hmax(hmax(father->lmax,father->rmax),
    110                      hmax(l_child->max,
    111                           hmax(r_child->max,l_child->rmax+r_child->lmax)));
    112 }
    113 //为什么这道题,有个小小的亮点,没有rnum ,lnum;
    114 //仔细一想确实是不需要的..
    115 
    116 
    117 
    118 void update(int l,int r,int num,int n) //更新函数  区间[l,r],更新为num。
    119 {
    120     int mid=(f[n].l+f[n].r)/2;
    121     if(f[n].l==l && f[n].r==r)
    122     {
    123         if(num==EMPTY)
    124         {
    125             f[n].lmax=f[n].rmax=f[n].max=f[n].len;
    126         }
    127         else f[n].lmax=f[n].rmax=f[n].max=0;
    128         f[n].color=num;
    129         return;
    130     }
    131 
    132     if(f[n].color!=0)
    133     make_down(n);
    134     if(mid>=r)
    135     update(l,r,num,n*2);
    136     else if(mid<l)
    137     update(l,r,num,n*2+1);
    138     else
    139     {
    140         update(l,mid,num,n*2);
    141         update(mid+1,r,num,n*2+1);
    142     }
    143     make_up(&f[n],&f[n*2],&f[n*2+1]);
    144 }
    145 
    146 int query(int max,int n)
    147 {
    148     int cur=0;
    149 
    150     if(f[n].l==f[n].r)
    151     return f[n].l;
    152     if(f[n].color!=0) //刚开始,这个别丢了,居然Running time error。
    153     make_down(n);
    154 
    155     if(f[n*2].max>=max)
    156     cur=query(max,n*2);
    157 
    158     else if(f[n*2].rmax+f[n*2+1].lmax>=max)
    159     return f[n*2].r-f[n*2].rmax+1;
    160 
    161     else if(f[n*2+1].max>=max)
    162     cur=query(max,n*2+1);
    163 
    164     make_up(&f[n],&f[n*2],&f[n*2+1]);
    165     return cur;
    166 }
    167 /*
    168 刚开始    左子树,
    169 然后是    左子树右边最大值+右子树左边最大值
    170 最后才是  右子树
    171 */
    172 
    173 void make_ini(int N,int M)
    174 {
    175     char a[10];
    176     int x,l,r,tmp;
    177     st hxl;
    178     while(M--)
    179     {
    180         scanf("%s",a);
    181         if(a[0]=='R')
    182         {
    183             update(1,N,EMPTY,1);
    184             tom.clear();
    185             printf("Reset Now
    ");
    186         }
    187         if(a[0]=='N')
    188         {
    189             scanf("%d",&x);
    190             if(f[1].max<x)
    191             {
    192                 printf("Reject New
    ");
    193             }
    194             else
    195             {
    196                 l=query(x,1);
    197                 r=l+x-1;
    198                 hxl.begin=l;
    199                 hxl.end=r;
    200                 vector<st>::iterator it;
    201                 it=upper_bound(tom.begin(),tom.end(),hxl,cmp1);//二分查找,前提是有序。
    202                 tom.insert(it,hxl);
    203                 printf("New at %d
    ",l);
    204                 update(l,r,HH,1);
    205             }
    206         }
    207         else if(a[0]=='F')
    208         {
    209             scanf("%d",&x);
    210             hxl.begin=x;
    211             hxl.end=x;
    212             vector<st>::iterator it;//容器的使用啊
    213             it=upper_bound(tom.begin(),tom.end(),hxl,cmp1);
    214 
    215             tmp=it-tom.begin()-1;
    216             if(tmp==-1 || tom[tmp].end<x)
    217             printf("Reject Free
    ");
    218             else
    219             {
    220                 printf("Free from %d to %d
    ",tom[tmp].begin,tom[tmp].end);
    221                 update(tom[tmp].begin,tom[tmp].end,EMPTY,1);
    222                 tom.erase(tom.begin()+tmp);
    223             }
    224         }
    225         else if(a[0]=='G')
    226         {
    227             scanf("%d",&x);
    228             if(x>tom.size())
    229             printf("Reject Get
    ");
    230             else
    231             printf("Get at %d
    ",tom[x-1].begin);//容器的下标也是从0开始,所以要减1
    232         }
    233     }
    234 }
    235 
    236 int main()
    237 {
    238     int N,M;
    239     while(scanf("%d%d",&N,&M)>0)
    240     {
    241         tom.clear();//这个必须要的。
    242         build(1,N,1);
    243         make_ini(N,M);
    244         printf("
    "); //!!
    245     }
    246     return 0;
    247 }
    View Code

    1002

      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<cstdlib>
      4 using namespace std;
      5 
      6 struct st
      7 {
      8     int l;
      9     int r;
     10     int num;
     11 }f[50002*4];
     12 int date[50002];
     13 
     14 void build(int l,int r,int n)
     15 {
     16     int mid=(l+r)/2;
     17     f[n].l=l;
     18     f[n].r=r;
     19     if(l==r)
     20     {
     21         f[n].num=date[l];
     22         return ;
     23     }
     24     build(l,mid,n*2);
     25     build(mid+1,r,n*2+1);
     26     f[n].num=f[n*2].num+f[n*2+1].num;
     27 }
     28 
     29 void update(int wz,int num,int n)
     30 {
     31     int mid=(f[n].l+f[n].r)/2;
     32     if(f[n].l==wz && f[n].r==wz)
     33     {
     34         if(f[n].num+num<0)
     35         f[n].num=0;
     36         else f[n].num+=num;
     37         return ;
     38     }
     39     if(wz<=mid)
     40         update(wz,num,n*2);
     41     else
     42         update(wz,num,n*2+1);
     43     f[n].num=f[n*2].num+f[n*2+1].num;
     44 }    
     45 
     46 int query(int l,int r,int n)
     47 {
     48     int sum=0,mid=(f[n].l+f[n].r)/2;
     49     if(f[n].l==l && f[n].r==r)
     50     {
     51         sum+=f[n].num;
     52         return sum;
     53     }
     54     if(mid<l)
     55     sum+=query(l,r,n*2+1);
     56     else if(mid>=r)
     57     sum+=query(l,r,n*2);
     58     else 
     59     {
     60         sum+=query(l,mid,n*2);
     61         sum+=query(mid+1,r,n*2+1);
     62     }
     63     return sum;
     64     
     65 }
     66 void makeini(int n,int T)
     67 {
     68     int i,j,k,l,r,wz,num;
     69     char a[10];
     70     for(i=1;i<=n;i++)
     71     scanf("%d",&date[i]);
     72     build(1,n,1);
     73     scanf("%s",a);
     74     while(a[0]!='E')
     75     {
     76         if(a[0]=='Q')
     77         {
     78             if(T>0)
     79             {
     80                 printf("Case %d:
    ",T);
     81                 T=0;
     82             }
     83             scanf("%d%d",&l,&r);
     84             printf("%d
    ",query(l,r,1));
     85         }
     86         else if(a[0]=='A')
     87         {
     88             scanf("%d%d",&wz,&num);
     89             update(wz,num,1);
     90         }
     91         else if(a[0]=='S')
     92         {
     93             scanf("%d%d",&wz,&num);
     94             update(wz,-num,1);
     95         }
     96         scanf("%s",a);
     97     }
     98 }
     99                     
    100 int main()
    101 {
    102     int T,n,i;
    103     while(scanf("%d",&T)>0)
    104     {
    105         for(i=1;i<=T;i++)
    106         {
    107             scanf("%d",&n);
    108             makeini(n,i);
    109         }
    110     }
    111     return 0;
    112 }
    View Code

    1004

     1 /*
     2 我把query()写成这样,错了。不懂...
     3 
     4 int query(int max,int n)
     5 {
     6     int mid=(f[n].l+f[n].r)/2,sum=-1;
     7 
     8     if(f[n].l==f[n].r)
     9     {
    10         f[n].max=f[n].max-max;
    11         return f[n].l;
    12     }
    13     if(f[n*2].max>=max)
    14         sum= query(max,n*2);
    15     else if(f[n*2+1].max>=max)
    16         sum= query(max,n*2+1);
    17     f[n].max=hxlmax(f[n*2].max,f[n*2+1].max);
    18     return sum;
    19 }
    20 
    21 */
    22 #include<stdio.h>
    23 #include<iostream>
    24 #include<cstdlib>
    25 using namespace std;
    26 
    27 struct st
    28 {
    29     int l;
    30     int r;
    31     int max;
    32 }f[200003*8];
    33 int H,W,N;
    34 
    35 void build(int l,int r,int n)
    36 {
    37     int mid=(l+r)/2;
    38     f[n].l=l;
    39     f[n].r=r;
    40     if(l==r)
    41     {
    42         f[n].max=W;
    43         return;
    44     }
    45     build(l,mid,n*2);
    46     build(mid+1,r,n*2+1);
    47     f[n].max=f[n*2].max>f[n*2+1].max? f[n*2].max:f[n*2+1].max;
    48 }
    49 
    50 int query(int max,int n)
    51 {
    52     int mid=(f[n].l+f[n].r)/2,sum=-1;
    53 
    54     if(f[n].l==f[n].r)
    55     {
    56         f[n].max=f[n].max-max;
    57         return f[n].l;
    58     }
    59     if(f[n*2].max>=max)
    60         sum= query(max,n*2);
    61     else if(f[n*2+1].max>=max)
    62         sum= query(max,n*2+1);
    63     f[n].max=f[n*2].max>f[n*2+1].max? f[n*2].max:f[n*2+1].max;
    64     return sum;
    65 }
    66 
    67 int main()
    68 {
    69     int wi,i;
    70     while(scanf("%d%d%d",&H,&W,&N)>0)
    71     {
    72         if(H>N)
    73             H=N;
    74         build(1,H,1);
    75         while(N--)
    76         {
    77             scanf("%d",&wi);
    78             if(wi>f[1].max)
    79                 printf("-1
    ");
    80             else
    81                 printf("%d
    ",query(wi,1));
    82         }
    83     }
    84     return 0;
    85 }
    View Code

    1005

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<cstring>
      6 #define N 100010
      7 using namespace std;
      8 
      9 int toleft[30][N];
     10 int Tree[30][N];
     11 int Sort[N];
     12 
     13 void build(int l,int r,int dep)
     14 {
     15     int mid=(l+r)/2,sum=mid-l+1,lpos,rpos,i;
     16     if(l==r) return ;
     17     for(i=l;i<=r;i++)
     18         if(Tree[dep][i]<Sort[mid]) sum--;
     19     lpos=l;
     20     rpos=mid+1;
     21     for(i=l;i<=r;i++)
     22     {
     23         if(Tree[dep][i]<Sort[mid])
     24         {
     25             Tree[dep+1][lpos++]=Tree[dep][i];
     26         }
     27         else if(Tree[dep][i]==Sort[mid] && sum>0)
     28         {
     29             Tree[dep+1][lpos++]=Tree[dep][i];
     30             sum--;
     31         }
     32         else
     33         {
     34             Tree[dep+1][rpos++]=Tree[dep][i];
     35         }
     36         toleft[dep][i]=toleft[dep][l-1]+lpos-l;
     37     }
     38     build(l,mid,dep+1);
     39     build(mid+1,r,dep+1);
     40 }
     41 
     42 int query(int L,int R,int l,int r,int dep,int k)
     43 {
     44     int mid=(L+R)/2,newl,newr,cur;
     45     if(l==r) return Tree[dep][l];
     46     cur=toleft[dep][r]-toleft[dep][l-1];
     47     if(cur>=k)
     48     {
     49         newl=L+toleft[dep][l-1]-toleft[dep][L-1];
     50         newr=newl+cur-1;
     51         return query(L,mid,newl,newr,dep+1,k);
     52     }
     53     else
     54     {
     55         newr=r+(toleft[dep][R]-toleft[dep][r]);//r的位置后移了
     56         newl=newr-(r-l-cur);
     57         return query(mid+1,R,newl,newr,dep+1,k-cur);
     58     }
     59 }
     60 
     61 void sc(int n)
     62 {
     63     int i,j;
     64     for(j=1;j<=4;j++)
     65     {
     66         printf("
    ");
     67         for(i=1;i<=10;i++)
     68             printf("%d ",Tree[j][i]);
     69     }
     70 }
     71 
     72 int main()
     73 {
     74     int T,n,m,i,l,r,k;
     75     scanf("%d",&T);
     76     {
     77         while(T--)
     78         {
     79             scanf("%d%d",&n,&m);
     80             memset(Tree,0,sizeof(Tree));
     81             for(i=1;i<=n;i++)
     82             {
     83                 scanf("%d",&Tree[0][i]);
     84                 Sort[i]=Tree[0][i];
     85             }
     86             sort(Sort+1,Sort+1+n);
     87             build(1,n,0);
     88             while(m--)
     89             {
     90                 scanf("%d%d%d",&l,&r,&k);//求区间[l,r]中第k大的数字
     91                 printf("%d
    ",query(1,n,l,r,0,k));
     92             }
     93         //    sc(n);
     94         }
     95 
     96     }
     97     return 0;
     98 }
     99 /* 学长的模板
    100 #include<iostream>
    101 #include<stdio.h>
    102 #include<algorithm>
    103 #include<string.h>
    104 
    105 using namespace std;
    106 
    107 #define N 100010
    108 
    109 int sorted[N];   //排序完的数组
    110 int toleft[30][N];   //toleft[i][j]表示第i层从1到k有多少个数分入左边
    111 int tree[30][N];  //表示每层每个位置的值
    112 
    113 void buildingTree(int l,int r,int dep)
    114 {
    115     if(l==r)    return;
    116     int mid = (l+r)>>1;
    117     int i,sum = mid-l+1;  //表示等于中间值而且被分入左边的个数
    118     for(i=l;i<=r;i++)
    119     {
    120         if(tree[dep][i]<sorted[mid])    sum--;
    121     }
    122     int lpos=l;
    123     int rpos=mid+1;
    124     for(i=l;i<=r;i++)
    125     {
    126         if(tree[dep][i]<sorted[mid])    //比中间的数小,分入左边
    127         {
    128             tree[dep+1][lpos++]=tree[dep][i];
    129         }
    130         else if(tree[dep][i]==sorted[mid]&&sum>0) //等于中间的数值,分入左边,直到sum==0后分到右边
    131         {
    132             tree[dep+1][lpos++]=tree[dep][i];
    133             sum--;
    134         }
    135         else  //右边
    136         {
    137             tree[dep+1][rpos++]=tree[dep][i];
    138         }
    139         toleft[dep][i] = toleft[dep][l-1] + lpos - l;   //从1到i放左边的个数
    140     }
    141     buildingTree(l,mid,dep+1);
    142     buildingTree(mid+1,r,dep+1);
    143 }
    144 
    145 //查询区间第k大的数,[L,R]是大区间,[l,r]是要查询的小区间
    146 int queryTree(int L,int R,int l,int r,int dep,int k)
    147 {
    148     if(l==r)    return tree[dep][l];
    149     int mid = (L+R)>>1;
    150     int cnt = toleft[dep][r] - toleft[dep][l-1];  //[l,r]中位于左边的个数
    151     if(cnt>=k)
    152     {
    153         int newl = L + toleft[dep][l-1] - toleft[dep][L-1]; //L+要查询的区间前被放在左边的个数
    154         int newr = newl + cnt - 1;  //左端点加上查询区间会被放在左边的个数
    155         return queryTree(L,mid,newl,newr,dep+1,k);
    156     }
    157     else
    158     {
    159         int newr = r + toleft[dep][R] - toleft[dep][r];
    160         int newl = newr - (r - l - cnt);
    161         return queryTree(mid+1,R,newl,newr,dep+1,k-cnt);
    162     }
    163 }
    164 
    165 
    166 int main()
    167 {
    168     int t;
    169     scanf("%d",&t);
    170     while(t--)
    171     {
    172         int n,m,i;
    173         scanf("%d%d",&n,&m);
    174         for(i=1;i<=n;i++)
    175         {
    176             scanf("%d",&tree[0][i]);
    177             sorted[i] = tree[0][i];
    178         }
    179         sort(sorted+1,sorted+1+n);
    180         buildingTree(1,n,0);
    181         while(m--)
    182         {
    183             int s,t,k;
    184             scanf("%d%d%d",&s,&t,&k);
    185             printf("%d
    ",queryTree(1,n,s,t,0,k));
    186         }
    187     }
    188     return 0;
    189 }*/
    View Code

    1006

      1 /*
      2 
      3 线段树延迟标记,感觉自己的方法不是很好。
      4 color==0  表示是纯色的,
      5 color==HH 表示是混色的。
      6 
      7   很久没有写线段树了...
      8 */
      9 
     10 #include<stdio.h>
     11 #include<iostream>
     12 #include<cstdlib>
     13 #define HH -1
     14 using namespace std;
     15 
     16 struct st
     17 {
     18     int l;
     19     int r;
     20     int color;
     21     int num;
     22 }f[100003*4];
     23 
     24 void build(int l,int r,int n)
     25 {
     26     int mid=(l+r)/2;
     27     f[n].l=l;
     28     f[n].r=r;
     29     f[n].color=0;
     30     f[n].num=1;
     31     if(l==r) return ;
     32     build(l,mid,n*2);
     33     build(mid+1,r,n*2+1);
     34 }
     35 
     36 void updown(int n)
     37 {
     38     f[n*2].color=0;
     39     f[n*2+1].color=0;
     40     f[n].color=HH;
     41     f[n*2].num=f[n].num;
     42     f[n*2+1].num=f[n].num;
     43 }
     44 
     45 void update(int l,int r,int size,int n)
     46 {
     47     int mid=(f[n].l+f[n].r)/2;
     48     if(f[n].l==l && f[n].r==r)
     49     {
     50         f[n].color=0;//纯色
     51         f[n].num=size;
     52         return ;
     53     }
     54     if(f[n].color==0)
     55         updown(n);
     56     if(mid<l)
     57         update(l,r,size,n*2+1);
     58     else if(mid>=r)
     59         update(l,r,size,n*2);
     60     else 
     61     {
     62         update(l,mid,size,n*2);
     63         update(mid+1,r,size,n*2+1);
     64     }
     65 }
     66 
     67 int query(int l,int r,int n)
     68 {
     69     int mid=(f[n].l+f[n].r)/2,sum=0;
     70     if(f[n].l==l && f[n].r==r && f[n].color==0)
     71     {
     72         return f[n].num*(f[n].r-f[n].l+1);
     73     }
     74     if(f[n].color==0)
     75         updown(n);
     76     if(mid>=r)
     77         sum+=query(l,r,n*2);
     78     else if(mid<l)
     79         sum+=query(l,r,n*2+1);
     80     else 
     81     {
     82         sum+=query(l,mid,n*2);
     83         sum+=query(mid+1,r,n*2+1);
     84     }
     85     return sum;
     86 }
     87 
     88 int main()
     89 {
     90     int T,i,n,Q,l,r,size;
     91     while(scanf("%d",&T)>0)
     92     {
     93         for(i=1;i<=T;i++)
     94         {
     95             scanf("%d",&n);
     96             build(1,n,1);
     97             scanf("%d",&Q);
     98             while(Q--)
     99             {
    100                 scanf("%d%d%d",&l,&r,&size);
    101                 update(l,r,size,1);
    102             }
    103             printf("Case %d: The total value of the hook is %d.
    ",i,query(1,n,1));
    104         }
    105     }
    106     return 0;
    107 }
    View Code

    1007

     1 /*
     2 
     3   水题
     4 
     5 */
     6 
     7 #include<stdio.h>
     8 #include<iostream>
     9 #include<cstdlib>
    10 using namespace std;
    11 
    12 struct st
    13 {
    14     int l;
    15     int r;
    16     int max;
    17 }f[200003*4];
    18 int date[200003];
    19 
    20 void build(int l,int r,int n)
    21 {
    22     int mid=(l+r)/2;
    23     f[n].l=l;
    24     f[n].r=r;
    25     if(l==r)
    26     {
    27         f[n].max=date[l];
    28         return;
    29     }
    30     build(l,mid,n*2);
    31     build(mid+1,r,n*2+1);
    32     f[n].max=f[n*2].max>f[n*2+1].max? f[n*2].max:f[n*2+1].max;
    33 }
    34 
    35 void update(int wz,int num,int n)
    36 {
    37     int mid=(f[n].l+f[n].r)/2;
    38     if(f[n].l==wz && f[n].r==wz)
    39     {
    40         f[n].max=num;
    41         return;
    42     }
    43     if(wz<=mid)
    44         update(wz,num,n*2);
    45     else if(wz>mid)
    46         update(wz,num,n*2+1);
    47     f[n].max=f[n*2].max>f[n*2+1].max? f[n*2].max:f[n*2+1].max;
    48 }
    49 
    50 int query(int l,int r,int n)
    51 {
    52     int mid=(f[n].l+f[n].r)/2,max,a,b;
    53     if(f[n].l==l && f[n].r==r)
    54     {
    55         return f[n].max;
    56     }
    57     if(mid>=r)
    58         max=query(l,r,n*2);
    59     else if(mid<l)
    60         max=query(l,r,n*2+1);
    61     else
    62     {
    63         a=query(l,mid,n*2);
    64         b=query(mid+1,r,n*2+1);
    65         max=a>b? a:b;
    66     }
    67     return max;
    68 }
    69 
    70 int main()
    71 {
    72     int i,N,M,l,r,wz,num;
    73     char a[5];
    74     while(scanf("%d%d",&N,&M)>0)
    75     {
    76         for(i=1;i<=N;i++)
    77             scanf("%d",&date[i]);
    78         build(1,N,1);
    79         for(i=1;i<=M;i++)
    80         {
    81             scanf("%s",a);
    82             if(a[0]=='Q')
    83             {
    84                 scanf("%d%d",&l,&r);
    85                 printf("%d
    ",query(l,r,1));
    86             }
    87             else if(a[0]=='U')
    88             {
    89                 scanf("%d%d",&wz,&num);
    90                 update(wz,num,1);
    91             }
    92         }
    93     }
    94     return 0;
    95 }
    View Code

    1008

      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<cstdlib>
      4 using namespace std;
      5 
      6 struct st
      7 {
      8     int l,r,lnum,rnum;
      9     int lmax,rmax,max;
     10     int len;
     11 }f[100003*4];
     12 int date[100003];
     13 
     14 int hxlmax(int x,int y)
     15 {
     16     return x>y? x:y;
     17 }
     18 
     19 void make_up(st *father, st *l_child, st *r_child)
     20 {
     21     father->lnum=l_child->lnum;
     22     father->rnum=r_child->rnum;
     23     if(l_child->rnum>=r_child->lnum)
     24     {
     25         father->lmax=l_child->lmax;
     26         father->rmax=r_child->rmax;
     27         father->max =hxlmax(l_child->max,r_child->max);
     28     }
     29     else
     30     {
     31         father->lmax=(l_child->lmax==l_child->len)? l_child->lmax+r_child->lmax: l_child->lmax;
     32         father->rmax=(r_child->rmax==r_child->len)? r_child->rmax+l_child->rmax: r_child->rmax;
     33         father->max =hxlmax(hxlmax(father->lmax,father->rmax),l_child->rmax+r_child->lmax);
     34     }
     35 }
     36 
     37 void build(int l,int r,int n)
     38 {
     39     int mid=(l+r)/2;
     40     f[n].l=l;
     41     f[n].r=r;
     42     f[n].len=f[n].r-f[n].l+1;
     43     if(l==r)
     44     {
     45         f[n].lnum=date[l];
     46         f[n].rnum=date[l];
     47         f[n].lmax=1;
     48         f[n].rmax=1;
     49         f[n].max=1;
     50         return;
     51     }
     52     build(l,mid,n*2);
     53     build(mid+1,r,n*2+1);
     54     make_up(&f[n],&f[n*2],&f[n*2+1]);
     55 }
     56 
     57 void update(int wz,int num,int n)
     58 {
     59     int mid=(f[n].l+f[n].r)/2;
     60     if(f[n].l==wz && f[n].r==wz)
     61     {
     62         f[n].lnum=num;
     63         f[n].rnum=num;
     64         return ;
     65     }
     66     if(mid>=wz)
     67         update(wz,num,n*2);
     68     else if(mid<wz)
     69         update(wz,num,n*2+1);
     70     make_up(&f[n],&f[n*2],&f[n*2+1]);
     71 }
     72 
     73 int query(int l,int r,int n)
     74 {
     75 
     76 }
     77 void make_ini(int n,int m)
     78 {
     79     int i,l,r,wz,num;
     80     char a[5];
     81     for(i=1;i<=n;i++)
     82         scanf("%d",&date[i]);
     83     build(1,n,1);
     84     while(m--)
     85     {
     86         scanf("%s",a);
     87         if(a[0]=='Q')
     88         {
     89             scanf("%d%d",&l,&r);
     90             printf("%d
    ",query(++l,++r,1));
     91         }
     92         else if(a[0]=='U')
     93         {
     94             scanf("%d%d",&wz,&num);
     95             update(++wz,num,1);
     96         }
     97     }
     98 }
     99 int main()
    100 {
    101     int T,n,m;
    102     while(scanf("%d",&T)>0)
    103     {
    104         while(T--)
    105         {
    106             scanf("%d%d",&n,&m);
    107             make_ini(n,m);
    108         }
    109     }
    110     return 0;
    111 }
    View Code

    1009

      1 /*
      2 hdu3333
      3 题意:给你一段很长的数字,求区间[l,r]里的和,满足数字重复出现的,只能算一次。
      4 
      5 测试数据10组,
      6 N 30000; 数字大小10^9;Q 10^5;
      7 
      8 用数组保存要询问的区间,离线算法..
      9 Next[]求出下一个重复出现数字的位置
     10 
     11 对x排序,用线段树更新max值。
     12 
     13 对初始的询问位置排序,输出结果。
     14 
     15 */
     16 #include<cstdio>
     17 #include<iostream>
     18 #include<cstdlib>
     19 #include<algorithm>
     20 #include<map>
     21 using namespace std;
     22 
     23 struct st
     24 {
     25     int l;
     26     int r;
     27     __int64 max;
     28 }f[30003*4];
     29 struct node
     30 {
     31     int begin;
     32     int end;
     33     __int64 max;
     34     int wz;
     35 }b[100003];
     36 int a[30003];
     37 int tom[30003];
     38 int Next[30003];
     39 
     40 map<int,int>hxl;
     41 
     42 bool cmp1(node n1,node n2) //起始位置从小到大排
     43 {
     44     return n1.begin<n2.begin;
     45 }
     46 
     47 bool cmp2(node n1,node n2) //back
     48 {
     49     return n1.wz<n2.wz;
     50 }
     51 
     52 void build(int l,int r,int n)
     53 {
     54     int mid=(l+r)/2;
     55     f[n].l=l;
     56     f[n].r=r;
     57     if(l==r)
     58     {
     59         f[n].max=tom[l];
     60         return;
     61     }
     62     build(l,mid,n*2);
     63     build(mid+1,r,n*2+1);
     64     f[n].max=f[n*2].max+f[n*2+1].max;
     65 }
     66 
     67 void update(int wz,int num,int n)
     68 {
     69     int mid=(f[n].l+f[n].r)/2;
     70     if(f[n].l==wz && f[n].r==wz)
     71     {
     72         f[n].max=num;
     73         return;
     74     }
     75     if(mid>=wz)
     76         update(wz,num,n*2);
     77     else if(mid<wz)
     78         update(wz,num,n*2+1);
     79     f[n].max=f[n*2].max+f[n*2+1].max;
     80 }
     81 
     82 __int64 query(int l,int r,int n)
     83 {
     84     int mid=(f[n].l+f[n].r)/2;
     85     if(f[n].l==l && f[n].r==r)
     86     {
     87         return f[n].max;
     88     }
     89     if(mid>=r)
     90         return query(l,r,n*2);
     91     else if(mid<l)
     92         return query(l,r,n*2+1);
     93     else
     94     {
     95         return query(l,mid,n*2)+query(mid+1,r,n*2+1);
     96     }
     97 }
     98 
     99 void make_then(int N,int Q)
    100 {
    101     int i,j,k;
    102     for(i=1;i<=N;i++)
    103     {
    104         tom[i]=0;
    105         Next[i]=0;
    106     }
    107     hxl.clear();
    108     for(i=N;i>=1;i--)
    109     {
    110         k=a[i];
    111         if(hxl.find(k)==hxl.end())
    112         {
    113             hxl[k]=i;
    114         }
    115         else
    116         {
    117             Next[i]=hxl[k];
    118             hxl[k]=i;
    119         }
    120     }// get Next[]
    121     hxl.clear();
    122     for(i=1;i<=N;i++)
    123     {
    124         k=a[i];
    125         if(hxl.find(k)==hxl.end())
    126         {
    127             tom[i]=k;
    128             hxl[k]=i;
    129         }
    130     }// get tom[]
    131 }
    132 
    133 void cs(int N,int Q)
    134 {
    135     int i,j;
    136     for(i=1;i<=N;i++)
    137         printf("%d ",Next[i]);
    138     printf("
    
    ");
    139     for(i=1;i<=N;i++)
    140         printf("%d ",tom[i]);
    141     printf("
    ");
    142 }
    143 
    144 void make_ini()
    145 {
    146     int Q,N,i,j,k,l,r;
    147     scanf("%d",&N);
    148     for(i=1;i<=N;i++)
    149         scanf("%d",&a[i]);
    150     scanf("%d",&Q);
    151     for(i=1;i<=Q;i++)
    152     {
    153         scanf("%d%d",&b[i].begin,&b[i].end);
    154         b[i].wz=i;
    155         b[i].max=0;
    156     }
    157     sort(b+1,b+1+Q,cmp1);
    158     make_then(N,Q);
    159 //    cs(N,Q);
    160     build(1,N,1);
    161     k=1;
    162     for(i=1;i<=Q;i++)
    163     {
    164         l=b[i].begin;
    165         r=b[i].end;
    166         if(k<l)
    167         {
    168             for(j=k;j<l;j++)
    169             {
    170                 if(Next[j]>0)
    171                 update(Next[j],a[j],1);
    172             }
    173             k=l;
    174         }
    175         b[i].max=query(l,r,1);
    176     }
    177     sort(b+1,b+1+Q,cmp2);
    178     for(i=1;i<=Q;i++)
    179         printf("%I64d
    ",b[i].max);    
    180 }
    181 
    182 int main()
    183 {
    184     int T;
    185     scanf("%d",&T);
    186     {
    187         while(T--)
    188         {
    189             make_ini();
    190         }
    191     }
    192     return 0;
    193 }
    View Code

    1010

      1 /*
      2 初学切割线,看陈俊学长的博客,
      3 感觉他的代码写得很漂亮。
      4 */
      5 
      6 #include<cstdio>
      7 #include<iostream>
      8 #include<cstdlib>
      9 #include<algorithm>
     10 using namespace std;
     11 
     12 
     13 struct Line
     14 {
     15     double x;
     16     double y1;
     17     double y2;
     18     int flag;
     19 }line[2004];
     20 struct node
     21 {
     22     int l;
     23     int r;
     24     double x;
     25     double y1,y2;
     26     int cover;
     27 }f[1004*8];
     28 double YY[2004];
     29 
     30 
     31 bool cmp(Line n1,Line n2)
     32 {
     33     return n1.x<n2.x;
     34 }
     35 
     36 void build(int l,int r,int n)
     37 {
     38     int mid=(l+r)/2;
     39     f[n].l=l;
     40     f[n].r=r;
     41     f[n].y1=YY[l];
     42     f[n].y2=YY[r];
     43     f[n].x=0;
     44     f[n].cover=0;
     45     if(l+1==r) return;
     46     build(l,mid,n*2);
     47     build(mid,r,n*2+1);
     48 }
     49 
     50 double update(Line cur,int n)
     51 {
     52     double now;
     53 
     54     if(cur.y1>=f[n].y2 || cur.y2<=f[n].y1) return 0;
     55     if(f[n].l+1==f[n].r)
     56     {
     57         if(f[n].cover<2)
     58         {
     59             f[n].cover+=cur.flag;
     60             f[n].x=cur.x;
     61             return 0;
     62         }
     63         else
     64         {
     65             now=(f[n].y2-f[n].y1)*(cur.x-f[n].x);
     66             f[n].cover+=cur.flag;
     67             f[n].x=cur.x;
     68         return now;
     69         }
     70     }
     71     return (update(cur,n*2)+update(cur,n*2+1));
     72 }
     73 
     74 void cs(int len)
     75 {
     76     int i;
     77     for(i=1;i<=len;i++)
     78     printf("%.3lf ",line[i].x);
     79     printf("
    ");
     80 
     81     for(i=1;i<=len;i++)
     82     printf("%.3lf ",YY[i]);
     83     printf("
    ");
     84 
     85 }
     86 
     87 void make_ini(int N)
     88 {
     89     int i,len=0;
     90     double x1,y1,x2,y2,cur=0;
     91     for(i=1;i<=N;i++)
     92     {
     93         scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
     94         line[++len].x=x1;
     95         line[len].y1=y1;
     96         line[len].y2=y2;
     97         line[len].flag=1;
     98 
     99         YY[len]=y1;
    100         YY[++len]=y2;
    101 
    102         line[len].x=x2;
    103         line[len].y1=y1;
    104         line[len].y2=y2;
    105         line[len].flag=-1;
    106     }
    107     sort(YY+1,YY+1+len);
    108     sort(line+1,line+1+len,cmp);
    109     build(1,len,1);
    110    //把这个建树放在了,两个sort之前,果断不对,检查N  time
    111    // cs(len);
    112     for(i=1;i<=len;i++)
    113     {
    114         cur+=update(line[i],1);
    115     }
    116     printf("%.2lf
    ",cur);
    117 
    118 }
    119 
    120 
    121 int main()
    122 {
    123     int T,N;
    124     while(scanf("%d",&T)>0)
    125     {
    126         while(T--)
    127         {
    128             scanf("%d",&N);
    129             make_ini(N);
    130         }
    131     }
    132     return 0;
    133 }
    View Code

    1014

     1 /*
     2 买票问题
     3 n个信息,
     4 x val,表示,价值为val的人,前面有x个人。
     5 .....
     6 
     7 最后输出最终的顺序
     8 
     9 */
    10 #include<cstdio>
    11 #include<iostream>
    12 #include<cstdlib>
    13 #include<algorithm>
    14 using namespace std;
    15 
    16 
    17 struct node
    18 {
    19     int l;
    20     int r;
    21     int max;
    22 }f[200003*4];
    23 int Date[200003];
    24 struct st
    25 {
    26     int begin;
    27     int val;
    28 }hxl[200003];
    29 
    30 
    31 void build(int l,int r,int n)
    32 {
    33     int mid=(l+r)/2;
    34     f[n].l=l;
    35     f[n].r=r;
    36     f[n].max=f[n].r-f[n].l+1;
    37     if(l==r)
    38     return ;
    39     build(l,mid,n*2);
    40     build(mid+1,r,n*2+1);
    41 }
    42 
    43 
    44 int query(int max,int n)
    45 {
    46     int cur=0;
    47     if(f[n].l==f[n].r && f[n].max==max)
    48     {
    49         f[n].max=0;
    50         return f[n].l;
    51     }
    52     if(f[n*2].max>=max)
    53     cur=query(max,n*2);
    54 
    55     else if(f[n*2+1].max>=max-f[n*2].max)
    56     cur=query(max-f[n*2].max,n*2+1);
    57 
    58     f[n].max=f[n*2].max+f[n*2+1].max;
    59     return cur;
    60 }
    61 
    62 int main()
    63 {
    64     int N;
    65     int wz,i;
    66     while(scanf("%d",&N)>0)
    67     {
    68         build(1,N,1);
    69         for(i=1;i<=N;i++)
    70         {
    71             scanf("%d%d",&hxl[i].begin,&hxl[i].val);
    72         }
    73         for(i=N;i>=1;i--)
    74         {
    75             wz=query(hxl[i].begin+1,1);
    76             Date[wz]=hxl[i].val;
    77         }
    78         for(i=1;i<=N;i++)
    79         {
    80             if(i==1)
    81             printf("%d",Date[i]);
    82             else printf(" %d",Date[i]);
    83             if(i==N)printf("
    ");
    84         }
    85     }
    86     return 0;
    87 }
    View Code

    1019

      1 /*
      2 统计周长
      3 */
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstdlib>
      8 #include<cstring>
      9 #include<algorithm>
     10 #define N 5003
     11 #define hxl 10003
     12 using namespace std;
     13 
     14 
     15 struct node
     16 {
     17     int begin;
     18     int end;
     19     int val;
     20     int flag;
     21 }Linex[N<<1],Liney[N<<1];
     22 int Hash[30000];
     23 
     24 
     25 bool cmp(node n1,node n2)
     26 {
     27     return n1.val<n2.val;
     28 }
     29 
     30 
     31 int make_x(int NN)
     32 {
     33     int sum=0,i,j;
     34     for(i=1;i<=NN;i++)
     35     {
     36         if(Linex[i].flag==1)
     37         {
     38             for(j=Linex[i].begin;j<Linex[i].end;j++)
     39             {
     40                 if(Hash[j]==0)
     41                 sum++;
     42                 Hash[j]++;
     43             }
     44         }
     45         else
     46         {
     47             for(j=Linex[i].begin;j<Linex[i].end;j++)
     48             {
     49                 if(Hash[j]==1)
     50                 sum++;
     51                 Hash[j]--;
     52             }
     53 
     54         }
     55     }
     56     return sum;
     57 }
     58 
     59 int make_y(int NN)
     60 {
     61     int sum=0,i,j;
     62     for(i=1;i<=NN;i++)
     63     {
     64         if(Liney[i].flag==1)
     65         {
     66             for(j=Liney[i].begin;j<Liney[i].end;j++)//不取等
     67             {
     68                 if(Hash[j]==0)
     69                 sum++;
     70                 Hash[j]++;
     71             }
     72         }
     73         else
     74         {
     75             for(j=Liney[i].begin;j<Liney[i].end;j++)
     76             {
     77                 if(Hash[j]==1)
     78                 sum++;
     79                 Hash[j]--;
     80             }
     81         }
     82     }
     83     return sum;
     84 }
     85 
     86 void make_ini(int NN)
     87 {
     88     int x1,y1,x2,y2,i,len=0,sum=0;
     89     for(i=1;i<=NN;i++)
     90     {
     91         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
     92         x1+=hxl;y1+=hxl;y2+=hxl;x2+=hxl;
     93 
     94         Linex[++len].val=x1;
     95         Linex[len].begin=y1;
     96         Linex[len].end=y2;
     97         Linex[len].flag=1;
     98 
     99         Liney[len].val=y1;
    100         Liney[len].begin=x1;
    101         Liney[len].end=x2;
    102         Liney[len].flag=1;
    103 
    104         Linex[++len].val=x2;
    105         Linex[len].begin=y1;
    106         Linex[len].end=y2;
    107         Linex[len].flag=-1;
    108 
    109         Liney[len].val=y2;
    110         Liney[len].begin=x1;
    111         Liney[len].end=x2;
    112         Liney[len].flag=-1;
    113     }
    114     sort(Linex+1,Linex+1+len,cmp);
    115     sort(Liney+1,Liney+1+len,cmp);
    116     memset(Hash,0,sizeof(Hash));
    117     sum+=make_x(len);
    118     memset(Hash,0,sizeof(Hash));
    119     sum+=make_y(len);
    120     printf("%d
    ",sum);
    121 }
    122 
    123 int main()
    124 {
    125     int NN;
    126     while(scanf("%d",&NN)>0)
    127     {
    128         make_ini(NN);
    129     }
    130     return 0;
    131 }
    View Code

    1023
    和第5题一样的。

    1026

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 #define HH  1//纯色
      7 using namespace std;
      8 
      9 struct node
     10 {
     11     int l;
     12     int r;
     13     int num;
     14     int color;
     15 }f[20003*8];
     16 struct st
     17 {
     18     int l;
     19     int r;
     20 }a[10003];
     21 int hxl[40003],hlen;
     22 int tom[40003],tlen;
     23 bool Hash[40005];
     24 
     25 int EF(int l,int r,int num)
     26 {
     27     int mid=(l+r)/2;
     28     while(l<r)
     29     {
     30         if(hxl[mid]>num)
     31             r=mid-1;
     32         else if(hxl[mid]<num)
     33             l=mid+1;
     34         else if(hxl[mid]==num)
     35             return mid;
     36         mid=(l+r)/2;
     37     }
     38     return mid;
     39 }
     40 
     41 void build(int l,int r,int n) 
     42 {
     43     int mid=(l+r)/2;
     44     f[n].l=l;
     45     f[n].r=r;
     46     f[n].num=0;
     47     f[n].color=0;
     48     if(l==r)
     49     {
     50     //    f[n].color=HH;
     51         return;
     52     }
     53     build(l,mid,n*2);
     54     build(mid+1,r,n*2+1);
     55 }
     56 
     57 void make_down(int n)
     58 {
     59     f[n*2].color=f[n*2+1].color=HH;
     60     f[n].color=0;
     61 
     62     f[n*2].num=f[n*2+1].num=f[n].num;
     63     f[n].num=0;
     64 }
     65 
     66 void update(int l,int r,int num,int n)
     67 {
     68     int mid=(f[n].l+f[n].r)/2;
     69     if(f[n].l==l && f[n].r==r)
     70     {
     71         f[n].color=HH;
     72         f[n].num=num;
     73         return ;
     74     }
     75     if(f[n].color==HH)
     76         make_down(n);
     77     if(mid>=r)
     78         update(l,r,num,n*2);
     79     else if(mid<l)
     80         update(l,r,num,n*2+1);
     81     else
     82     {
     83         update(l,mid,num,n*2);
     84         update(mid+1,r,num,n*2+1);
     85     }
     86 }
     87 
     88 void query(int l,int r,int n)
     89 {
     90     int mid=(f[n].l+f[n].r)/2;
     91     if(f[n].l==l && f[n].r==r)
     92     {
     93         if(f[n].color==HH && f[n].num>0)
     94         {
     95             Hash[f[n].num]=true;
     96             return ;
     97         }
     98     }
     99     if(f[n].l==f[n].r) return;
    100     if(f[n].color==HH)
    101         make_down(n);
    102     if(mid>=r)
    103         query(l,r,n*2);
    104     else if(mid<l)
    105         query(l,r,n*2+1);
    106     else 
    107     {
    108         query(l,mid,n*2);
    109         query(mid+1,r,n*2+1);
    110     }
    111     return ;
    112 }
    113 
    114 void make_ini(int n)
    115 {
    116     int i,l,r,max=0;
    117     tlen=0;
    118     for(i=1;i<=n;i++)
    119     {
    120         scanf("%d%d",&a[i].l,&a[i].r);
    121         tom[++tlen]=a[i].l;
    122         tom[++tlen]=a[i].r;
    123     }
    124     sort(tom+1,tom+1+tlen);
    125     memset(Hash,false,sizeof(Hash));
    126     hxl[1]=tom[1];
    127     hlen=1;
    128     for(i=2;i<=tlen;i++)
    129     {
    130         if(tom[i]!=tom[i-1])
    131             hxl[++hlen]=tom[i];
    132     }
    133     build(1,hlen,1);
    134     for(i=1;i<=n;i++)
    135     {
    136         l=EF(1,hlen,a[i].l);
    137         r=EF(1,hlen,a[i].r);
    138         update(l,r,i,1);
    139     }
    140     query(1,hlen,1);
    141     for(i=1;i<=n;i++)
    142         if(Hash[i]==true)
    143             max++;
    144     printf("%d
    ",max);
    145     
    146 }
    147 
    148 void sc()
    149 {
    150     int i;
    151     for(i=1;i<=tlen;i++)
    152         printf("%d ",tom[i]);
    153     printf("
    ");
    154 
    155     for(i=1;i<=hlen;i++)
    156         printf("%d ",hxl[i]);
    157     printf("
    ");
    158 
    159 
    160 }
    161 
    162 int main()
    163 {
    164     int T,n;
    165     while(scanf("%d",&T)>0)
    166     {
    167         while(T--)
    168         {
    169             scanf("%d",&n);
    170             make_ini(n);
    171         //    sc();
    172         }
    173     }
    174     return 0;
    175 }
    View Code
  • 相关阅读:
    JavaScript window对象属性和方法
    bzoj1878 [SDOI2009]HH的项链
    bzoj3289 Mato的文件管理
    bzoj2038 [2009国家集训队]小Z的袜子(hose)
    bzoj2333 [SCOI2011]棘手的操作
    bzoj2809 [Apio2012]dispatching
    hdu1512 Monkey King
    免费航班
    bzoj4538 [Hnoi2016]网络
    bzoj3207 花神的嘲讽计划Ⅰ
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3236446.html
Copyright © 2020-2023  润新知