Advertisement
Guest User

Faj Nlogn z komentarzami

a guest
Mar 26th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.57 KB | None | 0 0
  1. /*
  2.  * Author: Seokhwan Choi
  3.  * Time Complexity: O(N+M log (N+M))
  4.  * It is recommended to understand O((N+M) (log (N+M))^2) code before view this code
  5.  */
  6.  
  7. #include<stdio.h>
  8. #include<vector>
  9. #define MAXN 300100
  10. #define MAXLOGN 19
  11. int n,m;
  12. int p[MAXN];
  13. int c[MAXN];
  14. std::vector<int> el[MAXN];//list of child nodes
  15. int chk[MAXN];//DFS visit check
  16. int tv;//number of visited nodes in DFS
  17. int tm[MAXN];//DFS traverse order, tm[i] is i-th visited node
  18. int itm[MAXN];//node i is visited itm[i]-th in DFS
  19. int tend[MAXN];//subtree of i-th node is tm[i]~tend[i]
  20. int leaf[MAXN];//1 if leaf node(explosive), 0 otherwise, after renumbering nodes
  21. int np[MAXN];//parent node after renumbering nodes
  22. int nc[MAXN];//cost after renumbering nodes
  23. int nend[MAXN];//subtree of i-th node is i~nend[i] after renumbering
  24. long long int pnt[MAXN][2];//slope changing points, pnt[i][0]>=pnt[i][1]
  25. int pntn[MAXN];//number of slope changing points, doesn't exceed 2
  26. int it[1<<(MAXLOGN+1)];//segment tree, finds i which pnt[i][0] is maximum - so we can find maximum slope changing point
  27. long long int a[MAXN];//y=ax+b if x is larger than all slope changing points
  28. long long int b[MAXN];
  29. void dfs(int loc){//depth-first search for renumbering nodes
  30.     tv++;
  31.     chk[loc]=1;
  32.     tm[tv]=loc;
  33.     itm[loc]=tv;
  34.     int i;
  35.     for(i=0;i<(int)el[loc].size();i++){
  36.         dfs(el[loc][i]);
  37.     }
  38.     tend[loc]=tv;
  39. }
  40. void push(int loc,long long int val){//add slope changing point
  41.     pnt[loc][pntn[loc]]=val;//we add val in increasing order
  42.     pntn[loc]++;
  43.     it[loc+(1<<MAXLOGN)]=loc;
  44.     loc+=1<<MAXLOGN;
  45.     loc/=2;
  46.     while(loc>0){
  47.         if(pnt[it[loc*2]][0]>pnt[it[loc*2+1]][0]){
  48.             it[loc]=it[loc*2];
  49.         }
  50.         else{
  51.             it[loc]=it[loc*2+1];
  52.         }
  53.         loc/=2;
  54.     }
  55. }
  56. long long int pop(int start,int end){//pop maximum slope changing point in range[start,end]
  57.     start+=1<<MAXLOGN;
  58.     end+=1<<MAXLOGN;
  59.     long long int res=0;//pnt[res][0] should be maximum
  60.     //initially res=0, so pnt[res][0]=0, which is smaller than all other pnt[i][0]
  61.     while(start<=end){
  62.         if(start%2==1){
  63.             if(pnt[it[start]][0]>pnt[res][0]){
  64.                 res=it[start];
  65.             }
  66.             start++;
  67.         }
  68.         if(end%2==0){
  69.             if(pnt[it[end]][0]>pnt[res][0]){
  70.                 res=it[end];
  71.             }
  72.             end--;
  73.         }
  74.         start/=2;
  75.         end/=2;
  76.     }
  77.     long long int ret=pnt[res][0];//return value
  78.     long long int loc=res;//should erase pnt[loc][0]
  79.     pntn[loc]--;
  80.     if(pntn[loc]==0){
  81.         pnt[loc][0]=0;
  82.     }
  83.     else{//pntn[loc] becomes 2 to 1
  84.         pnt[loc][0]=pnt[loc][1];
  85.     }
  86.     loc+=1<<MAXLOGN;
  87.     loc/=2;
  88.     while(loc>0){
  89.         if(pnt[it[loc*2]][0]>pnt[it[loc*2+1]][0]){
  90.             it[loc]=it[loc*2];
  91.         }
  92.         else{
  93.             it[loc]=it[loc*2+1];
  94.         }
  95.         loc/=2;
  96.     }
  97.     return ret;
  98. }
  99. int main(){
  100.     int i;
  101.     long long int ta,tb;
  102.     scanf("%d%d",&n,&m);
  103.     for(i=2;i<=n+m;i++){
  104.         scanf("%d%d",&p[i],&c[i]);
  105.         el[p[i]].push_back(i);
  106.     }
  107.     dfs(1);//DFS from root node(node 1) to renumber nodes
  108.     for(i=1;i<=n+m;i++){
  109.         np[i]=itm[p[tm[i]]];
  110.         nc[i]=c[tm[i]];
  111.         if(tm[i]>n)leaf[i]=1;
  112.         nend[i]=tend[tm[i]];
  113.     }//renumbering finished
  114.     for(i=n+m;i>1;i--){
  115.         if(leaf[i]==1){//if i is leaf node
  116.             a[i]=1;
  117.             b[i]=-nc[i];
  118.             push(i,nc[i]);
  119.             push(i,nc[i]);
  120.         }
  121.         else{//we can see slope-changing points of subtree of node i
  122.             //add edge toward parent node to data
  123.             while(a[i]>1){
  124.                 b[i]+=pop(i,nend[i]);
  125.                 a[i]--;
  126.             }
  127.             ta=pop(i,nend[i]);
  128.             tb=pop(i,nend[i]);
  129.             push(i,ta+nc[i]);
  130.             push(i,tb+nc[i]);
  131.             b[i]-=nc[i];
  132.         }
  133.         a[np[i]]+=a[i];//we should only merge a,b to parent node
  134.         b[np[i]]+=b[i];//because we can see all slope-changing points of subtree
  135.     }
  136.     while(a[1]>0){
  137.         b[1]+=pop(1,nend[1]);
  138.         a[1]--;
  139.     }
  140.     printf("%lld\n",b[1]);
  141.     return 0;
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement