Scenic Popularity
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 117 Accepted Submission(s): 25
Problem Description 临近节日,度度熊们最近计划到室外游玩公园,公园内部包括了很多的旅游景点区和休息区,由于旅游景点很热门,导致景点区和休息区都聚集了很多人。所以度度熊在旅游之前想通过百度地图查看一下公园内各个地方的热门程度。
假设所有景点区和休息区都是X轴直线上的一系列顶点,所对应的坐标X
i 保证唯一。每个景点区有个初始的热度值,而一个休息区(坐标为X
i)的热度值等于离它距离最近的景点区X
j的热度值(距离定义为|X
i-X
j|),如果此休息区与两个景点区的距离一样,则休息区的热度值选择两个景点区中的热度值最大值,如果两个热度值都一样,则随意选择其中一个。
度度熊在出门之前会经常去查看百度地图,每次查看前会有某些景点区的热度值已发生改变,从而也会导致周围的休息区的热度值发生改变,然后度度熊想知道当前热度值<=R
k的顶点(包括景点区和休息区)有多少个
Input 输入数据的第一行是测试Case的个数(T<=100)。
每个Case的第一行是N(0<N<=10000),表示景点区和休息区的总数。
接着会有N行数据,每一列首先是顶点的X坐标Xi (0< X
i <=1e8),第二列是一个整数H
i(0=<H
i <=100000),如果H
i 不为0,则表示当前顶点为风景区且初始的热度值为H
i,否则表示当前顶点为休息区。这N行数据会按照坐标Xi递增的方式依次给出。
接着的一行数据是操作的次数K(K<=100),最后会有K行数据,每一行的第一列要么是’U’或者’Q’,’U’表示当前操作为更改热度操作,’Q’表示当前操作为查询操作。如果是更改操作,接着会有两列数据,分别是热度值要改变的风景区的下标L
k(0<=L
k<N)以及改变后的热度值V
k(0< V
k<=100000);如果是查询操作,第二列是要查询的热度范围R
k(0< R
k<=100000)
Output 对于第k组测试数据,第一行输出Case #k:,接下来对每次查询操作(即Q操作)会输出一个整数,表示满足条件的顶点数有多少个
Sample Input 1 4 10 0 20 3 30 0 40 2 3 Q 3 U 3 4 Q 3
Sample Output Case #1: 4 2
Source
2014年百度之星程序设计大赛 – 初赛(第二轮)
我的做法就是在修改的时候,暴力修改和这个点相关的。
找出景点会影响哪些休息区,然后修改的时候暴力,查询的时候树状数组求前n项和
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2014/5/25 14:22:19 4 File Name :E:\2014ACM\比赛\百度之星初赛2\A.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 const int MAXN = 100010; 22 long long c[MAXN]; 23 int lowbit(int x) 24 { 25 return x&(-x); 26 } 27 long long sum(int i) 28 { 29 long long ret = 0; 30 while(i > 0) 31 { 32 ret += c[i]; 33 i -= lowbit(i); 34 } 35 return ret; 36 } 37 void add(int i,long long val) 38 { 39 while(i <= 100000) 40 { 41 c[i] += val; 42 i += lowbit(i); 43 } 44 } 45 46 int s1[MAXN]; 47 int s2[MAXN]; 48 int sz1,sz2; 49 50 vector<int>vec1[10010]; 51 vector<int>vec2[10010]; 52 int a[10010]; 53 int b[10010]; 54 55 void calc(int u) 56 { 57 int id = lower_bound(s1,s1+sz1,s2[u]) - s1; 58 if(id == 0) 59 { 60 vec1[0].push_back(u); 61 vec2[u].push_back(0); 62 } 63 else if(id == sz1) 64 { 65 vec1[sz1-1].push_back(u); 66 vec2[u].push_back(sz1-1); 67 } 68 else 69 { 70 if(s2[u] - s1[id-1] < s1[id] - s2[u] ) 71 { 72 vec1[id-1].push_back(u); 73 vec2[u].push_back(id-1); 74 } 75 else if(s2[u] - s1[id-1] > s1[id] - s2[u]) 76 { 77 vec1[id].push_back(u); 78 vec2[u].push_back(id); 79 } 80 else 81 { 82 vec1[id-1].push_back(u); 83 vec2[u].push_back(id-1); 84 vec1[id].push_back(u); 85 vec2[u].push_back(id); 86 } 87 } 88 } 89 int get(int u) 90 { 91 if(vec2[u].size() == 1) 92 { 93 return a[vec2[u][0]]; 94 } 95 else 96 { 97 return max(a[vec2[u][0]],a[vec2[u][1]]); 98 } 99 } 100 101 int link[10010]; 102 103 int main() 104 { 105 //freopen("in.txt","r",stdin); 106 //freopen("out.txt","w",stdout); 107 int T; 108 int iCase = 0; 109 int n; 110 scanf("%d",&T); 111 while(T--) 112 { 113 iCase++; 114 printf("Case #%d:\n",iCase); 115 sz1 = 0;sz2 = 0; 116 memset(c,0,sizeof(c)); 117 int u,v; 118 scanf("%d",&n); 119 for(int i = 0;i < n;i++) 120 { 121 scanf("%d%d",&u,&v); 122 if(v == 0) 123 s2[sz2++] = u; 124 else 125 { 126 s1[sz1++] = u; 127 link[i] = sz1-1; 128 add(v,1); 129 a[sz1-1] = v; 130 } 131 vec1[i].clear(); 132 vec2[i].clear(); 133 } 134 for(int i = 0;i < sz2;i++) 135 calc(i); 136 for(int i = 0;i < sz2;i++) 137 { 138 b[i] = get(i); 139 add(b[i],1); 140 } 141 char op[10]; 142 int m; 143 scanf("%d",&m); 144 while(m--) 145 { 146 scanf("%s",op); 147 if(op[0] == 'Q') 148 { 149 scanf("%d",&u); 150 printf("%d\n",(int)sum(u)); 151 } 152 else 153 { 154 scanf("%d%d",&u,&v); 155 u = link[u]; 156 add(a[u],-1); 157 a[u] = v; 158 add(a[u],1); 159 for(int i = 0;i < vec1[u].size();i++) 160 { 161 int p = get(vec1[u][i]); 162 add(b[vec1[u][i]],-1); 163 b[vec1[u][i]] = p; 164 add(p,1); 165 } 166 } 167 } 168 } 169 return 0; 170 }