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
原文地址:https://www.cnblogs.com/tom987690183/p/3236446.html