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\n");

186         }

187         if(a[0]=='N')

188         {

189             scanf("%d",&x);

190             if(f[1].max<x)

191             {

192                 printf("Reject New\n");

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\n",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\n");

218             else

219             {

220                 printf("Free from %d to %d\n",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\n");

230             else

231             printf("Get at %d\n",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("\n"); //!!

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:\n",T);

 81                 T=0;

 82             }

 83             scanf("%d%d",&l,&r);

 84             printf("%d\n",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\n");

80             else

81                 printf("%d\n",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("\n");

 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\n",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\n",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.\n",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\n",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\n",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("\n\n");

139     for(i=1;i<=N;i++)

140         printf("%d ",tom[i]);

141     printf("\n");

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\n",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("\n");

 80 

 81     for(i=1;i<=len;i++)

 82     printf("%.3lf ",YY[i]);

 83     printf("\n");

 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\n",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("\n");

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\n",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\n",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("\n");

154 

155     for(i=1;i<=hlen;i++)

156         printf("%d ",hxl[i]);

157     printf("\n");

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

 

 

你可能感兴趣的:(线段树)