the_art_of_war

Untitled

Jan 24th, 2017
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.10 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef long long ll;
  5. typedef unsigned long long ull;
  6. int inf_int=1e8;
  7. ll inf_ll=1e15;
  8. typedef pair<int,int> pii;
  9. typedef pair<ll,ll> pll;
  10. #define pb push_back
  11. const double pi=3.1415926535898;
  12. #define dout if(debug) cout
  13. #define fi first
  14. #define se second
  15. #define sp setprecision
  16. #define sz size()
  17. bool debug=0;
  18. const int MAXN=2e5+10;
  19. int mod=1e9+7;
  20.  
  21. struct vertex
  22. {
  23. int val;
  24. vertex *l,*r;
  25.  
  26. ll sum;
  27. vertex(vertex *l,vertex *r)
  28. :l(l),r(r)
  29. {
  30. val=0;
  31. sum=0;
  32. if(l)
  33. {
  34. val+=l->val;
  35. sum+=l->sum;
  36. }
  37.  
  38. if(r)
  39. {
  40. val+=r->val;
  41. sum+=r->sum;
  42. }
  43. }
  44.  
  45. vertex(int val,ll sum)
  46. :val(val),sum(sum)
  47. {
  48. l=r=NULL;
  49. }
  50. };
  51.  
  52. vertex* build(int tl,int tr)
  53. {
  54. if(tl==tr)
  55. {
  56. return new vertex(0,0);
  57. }
  58. else
  59. {
  60. int tm=(tl+tr)>>1;
  61. return new vertex(
  62. build(tl,tm),
  63. build(tm+1,tr)
  64. );
  65. }
  66. }
  67. int rev[MAXN];
  68.  
  69. vertex* update(vertex* root,int tl,int tr,int pos)
  70. {
  71. if(tl==tr)
  72. {
  73. return new vertex(root->val+1,root->sum+rev[pos]);
  74. }
  75. else
  76. {
  77. int tm=(tl+tr)>>1;
  78. if(pos<=tm)
  79. {
  80. return new vertex(update(root->l,tl,tm,pos),root->r);
  81. }
  82. else
  83. {
  84. return new vertex(root->l,update(root->r,tm+1,tr,pos));
  85. }
  86. }
  87. }
  88.  
  89.  
  90. vertex* root[MAXN];
  91.  
  92. int get(vertex *root,vertex *root1,int tl,int tr,int k)
  93. {
  94. if(tl==tr)
  95. {
  96. return tl;
  97. }
  98. else
  99. {
  100. int sum=root->l->val-root1->l->val;
  101. int tm=(tl+tr)>>1;
  102.  
  103. if(sum>=k)
  104. {
  105. return get(root->l,root1->l,tl,tm,k);
  106. }
  107. else
  108. {
  109. return get(root->r,root1->r,tm+1,tr,k-sum);
  110. }
  111. }
  112. }
  113.  
  114. pair<int,ll> get_sum(vertex* root,vertex* root1,int tl,int tr,int l,int r)
  115. {
  116. if(l>r)
  117. return make_pair(0,0);
  118. if(tl==l && tr==r)
  119. {
  120. return make_pair(root->val-root1->val,root->sum-root1->sum);
  121. }
  122. else
  123. {
  124. int tm=(tl+tr)>>1;
  125. pair<int,ll> res1=get_sum(root->l,root1->l,tl,tm,l,min(r,tm));
  126. pair<int,ll> res2=get_sum(root->r,root1->r,tm+1,tr,max(tm+1,l),r);
  127. res1.fi+=res2.fi;
  128. res1.se+=res2.se;
  129. return res1;
  130. }
  131. }
  132.  
  133.  
  134. int n1;
  135.  
  136. int X[MAXN],Y[MAXN];
  137.  
  138. ll cost(int l,int r)
  139. {
  140. int mid=(r-l+1);
  141. int median=get(root[r],root[l-1],1,n1,mid);
  142. pair<int,ll> res1=get_sum(root[r],root[l-1],1,n1,1,median);
  143. pair<int,ll> res2=get_sum(root[r],root[l-1],1,n1,median+1,n1);
  144. ll ans=res2.se-res1.se;
  145. if(res1.fi>res2.fi)
  146. {
  147. ans+=1ll*rev[median]*(res1.fi-res2.fi);
  148. }
  149. else
  150. {
  151. ans-=1ll*rev[median]*(res1.fi-res2.fi);
  152. }
  153. return ans;
  154. }
  155.  
  156. void calc(ll** dp,int k,int l,int r,int opt_l,int opt_r)
  157. {
  158. if(l>r || opt_l>opt_r)
  159. return;
  160. int mid=(l+r)>>1;
  161.  
  162. ll ans=inf_ll;
  163. int ind=-1;
  164.  
  165. for(int i=opt_l;i<=opt_r && i<mid;++i)
  166. {
  167. ll val=dp[k-1][i]+cost(i+1,mid);
  168. if(val<ans)
  169. {
  170. ans=val;
  171. ind=i;
  172. }
  173. }
  174. dp[k][mid]=ans;
  175. calc(dp,k,l,mid-1,opt_l,ind);
  176. calc(dp,k,mid+1,r,ind,opt_r);
  177. }
  178. void solve()
  179. {
  180. int n,k;
  181. cin >> n >> k;
  182. ll** dp = new ll* [k+1];
  183. for(int i=1;i<=k;++i)
  184. dp[i]=new ll[n+1];
  185. vector<pair<double,int> > a;
  186. vector<int> C;
  187.  
  188. for(int i=1;i<=n;++i)
  189. {
  190. int x,y;
  191. cin >> x >> y;
  192. a.pb({(x+y)/2.0,i});
  193. X[i]=x;
  194. Y[i]=y;
  195. C.pb(x);
  196. C.pb(y);
  197. }
  198. sort(a.begin(),a.end());
  199. sort(C.begin(),C.end());
  200. map<int,int> mp;
  201. int z=1;
  202. for(int v:C)
  203. {
  204. if(mp[v]==0)
  205. {
  206. mp[v]=z;
  207. rev[z]=v;
  208. ++z;
  209. }
  210. }
  211. n1=2*n+15;
  212. root[0]=build(1,n1);
  213. for(int i=1;i<=n;++i)
  214. {
  215. int ind=a[i-1].se;
  216. root[i]=update(root[i-1],1,n1,mp[X[ind]]);
  217. root[i]=update(root[i],1,n1,mp[Y[ind]]);
  218. }
  219.  
  220. for(int i=1;i<=k;++i)
  221. {
  222. for(int e=1;e<=n;++e)
  223. {
  224. dp[i][e]=inf_ll;
  225. }
  226. }
  227. dp[1][0]=0;
  228. for(int i=1;i<=n;++i)
  229. {
  230. dp[1][i]=cost(1,i);
  231. }
  232. for(int i=2;i<=k;++i)
  233. {
  234. dp[i][0]=0;
  235. calc(dp,i,1,n,0,n);
  236. }
  237.  
  238. cout << dp[k][n]<<endl;
  239.  
  240.  
  241.  
  242.  
  243.  
  244. }
  245.  
  246.  
  247. #define FILE "hamiltonian"
  248. int main()
  249. {
  250. #ifdef zxc
  251. freopen("input.txt","r",stdin);
  252. // freopen("output.txt","w",stdout);
  253. #endif // zxc
  254.  
  255.  
  256. // freopen(FILE".in","r",stdin);
  257. // freopen(FILE".out","w",stdout);
  258.  
  259.  
  260. // freopen("input.txt","r",stdin);
  261. // freopen("output.txt","w",stdout);
  262.  
  263.  
  264. if(!debug)
  265. {
  266. ios_base::sync_with_stdio(0);
  267. cin.tie(0);
  268. cout.tie(0);
  269. }
  270.  
  271. int t=1;
  272. // cin >> t;
  273. while(t--)
  274. solve();
  275. return 0;
  276. }
Advertisement
Add Comment
Please, Sign In to add comment