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 }
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 }
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 }
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 }*/
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }