Advertisement
cosminBoaca

Untitled

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