记录编号 326341 评测结果 AAAWEETTTT
题目名称 零食店 最终得分 30
用户昵称 GravatarAntiLeaf 是否通过 未通过
代码语言 C++ 运行时间 5.907 s
提交时间 2016-10-21 07:26:39 内存使用 0.54 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. #include<queue>
  6. #include<ext/pb_ds/assoc_container.hpp>
  7. #include<ext/pb_ds/tree_policy.hpp>
  8. using namespace std;
  9. /*struct tree{
  10. #define siz(x) ((x)?((x)->size):(0))
  11. static const double BAL=0.65;
  12. static const int maxn=100010;
  13. struct node{//Scapegoat Tree
  14. int data,size;
  15. node *lc,*rc,*prt;
  16. node(int d):data(d),size(1),lc(NULL),rc(NULL),prt(NULL){}
  17. inline void refresh(){size=siz(lc)+siz(rc)+1;}
  18. }*root;
  19. int data[maxn],cnt;
  20. tree(){root=NULL;}
  21. void clear(){
  22. removetree(root);
  23. root=NULL;
  24. }
  25. void insert(int x){
  26. node *rt=insert(new node(x));
  27. if(rt)rebuild(rt);
  28. }
  29. void erase(int x){
  30. node *rt=erase(find(x));
  31. if(rt)rebuild(rt);
  32. }
  33. int rank(int x){
  34. node *rt=root;
  35. int ans=0;
  36. while(rt){
  37. if(x<=rt->data)rt=rt->lc;
  38. else{
  39. ans+=siz(rt->lc)+1;
  40. rt=rt->rc;
  41. }
  42. }
  43. return ans;
  44. }
  45. node *insert(node *x){
  46. if(!root){
  47. root=x;
  48. return NULL;
  49. }
  50. node *rt=root;
  51. for(;;){
  52. if(x->data<rt->data){
  53. if(rt->lc)rt=rt->lc;
  54. else{
  55. rt->lc=x;
  56. break;
  57. }
  58. }
  59. else{
  60. if(rt->rc)rt=rt->rc;
  61. else{
  62. rt->rc=x;
  63. break;
  64. }
  65. }
  66. }
  67. x->prt=rt;
  68. x=NULL;
  69. while(rt){
  70. rt->refresh();
  71. if(max(siz(rt->lc),siz(rt->rc))>BAL*rt->size)x=rt;
  72. rt=rt->prt;
  73. }
  74. return x;
  75. }
  76. node *find(int x){
  77. node *rt=root;
  78. while(rt){
  79. if(x==rt->data)return rt;
  80. else if(x<rt->data)rt=rt->lc;
  81. else rt=rt->rc;
  82. }
  83. return NULL;
  84. }
  85. node *erase(node *x){
  86. if(x->lc&&x->rc){
  87. node *y=findmax(x->lc);
  88. x->data=y->data;
  89. return erase(y);
  90. }
  91. if(!x->lc&&!x->rc){
  92. if(x->prt){
  93. if(x==x->prt->lc)x->prt->lc=NULL;
  94. else x->prt->rc=NULL;
  95. }
  96. else root=NULL;
  97. }
  98. else if(x->lc&&!x->rc){
  99. x->lc->prt=x->prt;
  100. if(x->prt){
  101. if(x==x->prt->lc)x->prt->lc=x->lc;
  102. else x->prt->rc=x->lc;
  103. }
  104. else root=x->lc;
  105. }
  106. else if(!x->lc&&x->rc){
  107. x->rc->prt=x->prt;
  108. if(x->prt){
  109. if(x==x->prt->lc)x->prt->lc=x->rc;
  110. else x->prt->rc=x->rc;
  111. }
  112. else root=x->rc;
  113. }
  114. node *rt=x->prt;
  115. delete x;
  116. x=NULL;
  117. while(rt){
  118. rt->refresh();
  119. if(max(siz(rt->lc),siz(rt->rc))>BAL*rt->size)x=rt;
  120. rt=rt->prt;
  121. }
  122. return x;
  123. }
  124. void rebuild(node *rt){
  125. cnt=0;
  126. zorder(rt);
  127. node *x=rebuild(1,cnt);
  128. x->prt=rt->prt;
  129. if(rt->prt){
  130. if(rt==rt->prt->lc)rt->prt->lc=x;
  131. else rt->prt->rc=x;
  132. }
  133. else root=x;
  134. removetree(rt);
  135. }
  136. void zorder(node *x){
  137. if(!x)return;
  138. zorder(x->lc);
  139. data[++cnt]=x->data;
  140. zorder(x->rc);
  141. }
  142. node *rebuild(int l,int r){
  143. if(l>r)return NULL;
  144. if(l==r)return new node(data[l]);
  145. int mid=(l+r)>>1;
  146. node *x=new node(data[mid]);
  147. x->lc=rebuild(l,mid-1);
  148. if(x->lc)x->lc->prt=x;
  149. x->rc=rebuild(mid+1,r);
  150. if(x->rc)x->rc->prt=x;
  151. x->refresh();
  152. return x;
  153. }
  154. void removetree(node *x){
  155. if(!x)return;
  156. removetree(x->lc);
  157. removetree(x->rc);
  158. delete x;
  159. }
  160. node *findmax(node *x){
  161. while(x->rc)x=x->rc;
  162. return x;
  163. }
  164. #undef siz
  165. }T;*/
  166. using namespace __gnu_pbds;
  167. const int maxn=110,maxe=10010;
  168. tree<int,null_mapped_type,less_equal<int>,rb_tree_tag,tree_order_statistics_node_update>T;
  169. struct edge{int to,prev,w;}e[maxe<<1];
  170. struct Q{
  171. int c,d,id;
  172. Q(int c,int d,int id):c(c),d(d),id(id){}
  173. bool operator<(const Q &q)const{return c<q.c;}
  174. };
  175. void addedge(int,int,int);
  176. void work(int);
  177. void SPFA(int);
  178. int n,m,k,last[maxn]={0},len=0,w[maxn],t[maxn],rnk[maxn]={0},ans[maxn],dis[maxn];
  179. vector<Q>qu[maxn];
  180. queue<int>q;
  181. bool inq[maxn]={0};
  182. int main(){
  183. #define MINE
  184. #ifdef MINE
  185. freopen("snackstore.in","r",stdin);
  186. freopen("snackstore.out","w",stdout);
  187. #endif
  188. scanf("%d%d%d",&n,&m,&k);
  189. for(int i=1;i<=n;i++){
  190. scanf("%d",&w[i]);
  191. t[i]=w[i];
  192. }
  193. sort(t+1,t+n+1);
  194. for(int i=1;i<=n;i++){
  195. int p=lower_bound(t+1,t+n+1,w[i])-t;
  196. while(rnk[p])p++;
  197. rnk[p]=i;
  198. }
  199. //for(int i=1;i<=n;i++)printf("%d ",rnk[i]);printf("\n");
  200. for(int i=1;i<=m;i++){
  201. int x,y,z;
  202. scanf("%d%d%d",&x,&y,&z);
  203. addedge(x,y,z);
  204. addedge(y,x,z);
  205. }
  206. for(int i=1;i<=k;i++){
  207. int s,c,d;
  208. scanf("%d%d%d",&s,&c,&d);
  209. qu[s].push_back(Q(c,d,i));
  210. }
  211. for(int i=1;i<=n;i++)work(i);
  212. for(int i=1;i<=k;i++)printf("%d\n",ans[i]);
  213. #ifndef MINE
  214. printf("\n-------------------------DONE-------------------------\n");
  215. for(;;);
  216. #endif
  217. return 0;
  218. }
  219. void addedge(int x,int y,int z){
  220. e[++len].to=y;
  221. e[len].w=z;
  222. e[len].prev=last[x];
  223. last[x]=len;
  224. }
  225. void work(int x){
  226. //printf("work(%d)\n",x);
  227. T.clear();
  228. memset(dis,63,sizeof(dis));
  229. dis[x]=0;
  230. q.push(x);
  231. SPFA(0);
  232. /*for(int i=1;i<=n;i++){
  233. if(dis[i]!=0x3f3f3f3f)printf("%d ",dis[i]);
  234. else printf("INF ");
  235. }printf("\n");*/
  236. vector<Q>&a=qu[x];
  237. sort(a.begin(),a.end());
  238. int cnt=a.size(),cur=1;
  239. for(int i=0;i<cnt;i++){
  240. //printf("i=%d c=%d d=%d\n",i,a[i].c,a[i].d);
  241. while(cur<=n&&w[rnk[cur]]<=a[i].c){
  242. q.push(rnk[cur]);
  243. inq[rnk[cur]]=true;
  244. cur++;
  245. }
  246. SPFA(a[i].c);
  247. /*for(int j=1;j<=n;j++){
  248. if(dis[j]!=0x3f3f3f3f)printf("%d ",dis[j]);
  249. else printf("INF ");
  250. }printf("\n");*/
  251. ans[a[i].id]=T.order_of_key(a[i].d+1);
  252. //ans[a[i].id]=T.rank(a[i].d+1);
  253. }
  254. }
  255. void SPFA(int c){
  256. int x;
  257. while(!q.empty()){
  258. x=q.front();
  259. //assert(q.size()<20);
  260. q.pop();
  261. inq[x]=false;
  262. for(int i=last[x];i;i=e[i].prev)if(dis[e[i].to]>dis[x]+e[i].w){
  263. if(dis[e[i].to]!=0x3f3f3f3f)T.erase(dis[e[i].to]);
  264. dis[e[i].to]=dis[x]+e[i].w;
  265. T.insert(dis[e[i].to]);
  266. //assert(T.size()<10);
  267. if(w[e[i].to]<=c&&!inq[e[i].to]){
  268. inq[e[i].to]=true;
  269. q.push(e[i].to);
  270. }
  271. }
  272. }
  273. }
  274. /*
  275. 5 5 2
  276. 1 2 3 4 5
  277. 1 2 1
  278. 1 3 4
  279. 2 3 2
  280. 1 4 3
  281. 2 5 1
  282. 1 1 3
  283. 2 1 2
  284. Answer:
  285. 2
  286. 3
  287. */
  288. /*
  289. 5 6 6
  290. 7 2 5 1 6
  291. 1 2 1
  292. 3 1 2
  293. 5 4 4
  294. 3 5 1
  295. 2 3 2
  296. 1 5 3
  297. 3 1 10
  298. 4 7 9
  299. 2 6 3
  300. 1 3 1
  301. 5 7 3
  302. 5 7 4
  303. Answer:
  304. 3
  305. 4
  306. 3
  307. 1
  308. 3
  309. 4
  310. */
  311. /*
  312. 本题询问非常多,而在线的话不是时间不够就是附加信息太多无法维护,因此考虑离线。
  313. 把询问按起点分类,然后按照c从小到大依次处理各询问,用平衡树维护点的距离,
  314. 每次按照新的c重跑SPFA并更新答案。
  315. 本来想用pb_ds...然而可重好像要用less_equal,不太保险啊不敢用...
  316. 这个平衡树是从普通平衡树抄过来的......
  317. */