• 【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
    ",cnt);
    130         printf("
    ");
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    PHP 小方法之 算生日
    PHP 小方法之 随机生成几位字符串
    PHP 小方法之 过滤参数
    PHP 小方法之 计算两个时间戳之间相差的日时分秒
    PHP 小方法之 仿百度蜘蛛采集
    PHP 小方法之 显示 今天 昨天 上周 上月 近三月 的时间
    PHP保留两位小数的几种方法
    mysql 常用命令(一)
    PHP数据库页面增删查
    PHP数据库登陆注册简单做法
  • 原文地址:https://www.cnblogs.com/myx12345/p/11593785.html
Copyright © 2020-2023  润新知