【HDOJ6609】Find the answer(线段树)

题意:给定一个n个正整数的数列,第i项为w[i],对于每个i,你要从[1,i-1]中选择一些变成0,使得变化后[1,i]的总和小于m,每次询问最少要变几个

n<=2e5,m<=1e9,1<=w[i]<=m

思路:显然每次贪心删最大的,直接开权值线段树,每次询问就在直接树上二分

开始交了几发TLE+MLE,是没有离散化的锅,把w[i]离散化就行

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 #define N  210000
 10 #define M  1100000
 11 #define fi first
 12 #define se second
 13 #define MP make_pair
 14 #define pi acos(-1)
 15 #define mem(a,b) memset(a,b,sizeof(a))
 16 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 17 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 18 #define lowbit(x) x&(-x)
 19 #define Rand (rand()*(1<<16)+rand())
 20 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 21 #define ls p<<1
 22 #define rs p<<1|1
 23 
 24 const ll MOD=998244353,inv2=(MOD+1)/2;
 25       double eps=1e-6;
 26       ll INF=1e14;
 27 
 28 struct node
 29 {
 30     int num;
 31     ll sum;
 32 }t[N<<2];
 33 
 34 struct arr
 35 {
 36     int x,id;
 37 }a[N];
 38 
 39 bool cmp(arr a,arr b)
 40 {
 41     return a.x<b.x;
 42 }
 43 
 44 int b[N],c[N],q[N];
 45 
 46 int cnt,root,n,m;
 47 
 48 int read()
 49 {
 50    int v=0,f=1;
 51    char c=getchar();
 52    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 53    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 54    return v*f;
 55 }
 56 
 57 void build(int l,int r,int p)
 58 {
 59     t[p].num=t[p].sum=0;
 60     if(l==r) return;
 61     int mid=(l+r)>>1;
 62     build(l,mid,ls);
 63     build(mid+1,r,rs);
 64 }
 65 
 66 int query(int l,int r,ll s,int p)
 67 {
 68     if(p==0) return 0;
 69     if(l==r)
 70     {
 71         if(s<=m) return 0;
 72         ll t=(s-m)/c[l];
 73         if((s-m)%c[l]) t++;
 74         return t;
 75     }
 76     int mid=(l+r)>>1;
 77     ll tmp=t[rs].sum;
 78     if(s-tmp<=m) return query(mid+1,r,s,rs);
 79      else
 80      {
 81          return t[rs].num+query(l,mid,s-tmp,ls);
 82      }
 83 }
 84 
 85 void update(int l,int r,int x,int p)
 86 {
 87     t[p].num++;
 88     t[p].sum+=c[x];
 89     if(l==r) return;
 90     int mid=(l+r)>>1;
 91     if(x<=mid) update(l,mid,x,ls);
 92      else update(mid+1,r,x,rs);
 93 }
 94 
 95 int main()
 96 {
 97     //freopen("1.in","r",stdin);
 98     //freopen("1.out","w",stdout);
 99     int cas=read();
100     cnt=0;
101     while(cas--)
102     {
103         n=read(),m=read();
104         rep(i,1,n)
105         {
106             a[i].x=read();
107             a[i].id=i;
108         }
109         rep(i,1,n) q[i]=a[i].x;
110         sort(a+1,a+n+1,cmp);
111         b[a[1].id]=1; c[1]=a[1].x;
112         int t=1;
113         rep(i,2,n)
114          if(a[i].x==a[i-1].x) b[a[i].id]=t;
115           else
116           {
117               t++;
118               b[a[i].id]=t;
119               c[t]=a[i].x;
120           }
121         build(1,t,1);
122         ll s=0;
123         rep(i,1,n)
124         {
125             s+=q[i];
126             printf("%d ",query(1,t,s,1));
127             update(1,t,b[i],1);
128         }
129         //printf("cnt=%d\n",cnt);
130         printf("\n");
131     }
132     return 0;
133 }

 

posted on 2019-09-26 19:09  myx12345  阅读(180)  评论(0编辑  收藏  举报

导航