Advertisement
cosminBoaca

Untitled

Apr 5th, 2015
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.42 KB | None | 0 0
  1. /*
  2.  *Cosmin Boaca 334CC
  3.  */
  4. #include<stdio.h>
  5. #include<assert.h>
  6. #define infile "aib.in"
  7. #define outfile "aib.out"
  8. #define nmax 200000
  9. int arb[nmax]; //aici vom salva arborele de intervale
  10. int n; //numarul de elemente
  11. int poz,val; //le vom volosi la adaugarea in arbore
  12. int a,b; //interalul pe care se cauta suma la un query pe un interval
  13.  
  14. void add(int rad, int st, int dr)
  15. {
  16.     if(st==dr) { arb[rad]+=val; return; } //adaugam valoarea la pozitie
  17.     int mij=(st+dr)>>1;
  18.     arb[rad]=0;
  19.     if(poz<=mij && (rad<<1)<nmax) add(rad<<1,st,mij);
  20.     if(mij<poz && ((rad<<1)|1)<nmax) add((rad<<1)|1,mij+1,dr);
  21.     if((rad<<1)<nmax) arb[rad]+=arb[rad<<1];
  22.     if(((rad<<1)|1)<nmax) arb[rad]+=arb[(rad<<1)|1];
  23. }
  24.  
  25. int query(int rad, int st, int dr)
  26. {
  27.     if(a<=st && dr<=b) return arb[rad]; //suma
  28.     int mij=(st+dr)>>1;
  29.     int sum=0;
  30.     if(a<=mij && (rad<<1)<nmax) sum+=query(rad<<1,st,mij);
  31.     if(mij<b && ((rad<<1)|1)<nmax) sum+=query((rad<<1)|1,mij+1,dr);
  32.     return sum;
  33. }
  34.  
  35. int query2(int rad, int st, int dr, int sum)
  36. {
  37.     if(arb[rad]==sum) return dr-st+1; //numarul de elemente ale acestui subarbore
  38.     if(arb[rad]<sum || st==dr) return -1; //nu se poate obtine
  39.     int mij=(st+dr)>>1;
  40.     if((rad<<1)<nmax && sum<=arb[rad<<1]) return query2(rad<<1,st,mij,sum);
  41.     else if(((rad<<1)|1)<nmax)
  42.     {
  43.         int x=query2((rad<<1)|1,mij+1,dr,sum-arb[rad<<1]);
  44.         if(x<0) return -1;
  45.         return mij-st+1+x;
  46.     }
  47.     else return -1;
  48. }
  49.  
  50. int main()
  51. {
  52.     int t,u;
  53.     freopen(infile,"r",stdin);
  54.     freopen(outfile,"w",stdout);
  55.  
  56.     scanf("%d %d\n",&n,&t);
  57.  
  58.     //citim sirul initial
  59.     for(poz=1;poz<=n;poz++)
  60.     {
  61.         scanf("%d",&val);
  62.         add(1,1,n);
  63.     }
  64.  
  65.     //executam operatiile
  66.     int check = 1;
  67.     while(t--)
  68.     {
  69.         scanf("%d ",&u); //tipul operatiei
  70.         assert(u == 1);
  71.         if(!u)
  72.         { //daca avem modificarea unei valori
  73.             scanf("%d %d\n",&poz,&val);
  74.             add(1,1,n);
  75.         }
  76.         else if(u==1)
  77.         { //suma unui interval
  78.             scanf("%d %d\n",&a,&b);
  79.             assert(a == check);
  80.             assert(b == check);
  81.             printf("%d\n",query(1,1,n));
  82.         }
  83.         else if(u==2)
  84.         { //pozitia pentru obtinerea sumei
  85.             scanf("%d\n",&val);
  86.             printf("%d\n",query2(1,1,n,val));
  87.         }
  88.         check++;
  89.     }
  90.  
  91.     fclose(stdin);
  92.     fclose(stdout);
  93.     return 0;
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement