BZOJ4378 : [POI2015]Logistyka

对于每个询问,设不小于$s$的个数为$cnt$,小于$s$的和为$sum$。

那么如果可以进行$s$轮,当且仅当$sum\geq (c-cnt)\times s$。

权值线段树维护,时间复杂度$O(m\log m)$。

证明:

如果$cnt\geq c$,那么显然可以每次取$c$个。

否则如果$sum\geq (c-cnt)\times s$,那么小于$s$的个数必然不小于$c$,可以每次取最大的$c$个来完成。

当$sum<(c-cnt)\times s$时,那么无论怎么取,都是做不到$s$轮的。

#include<cstdio>
#include<algorithm>
const int N=1000010,M=2100000;
int n,m,i,x,y,a[N],b[N],cb,op[N][3],v[M],cnt;long long s[M],sum;
inline void read(int&a){char c;while(!(((c=getchar())>=‘0‘)&&(c<=‘9‘)));a=c-‘0‘;while(((c=getchar())>=‘0‘)&&(c<=‘9‘))(a*=10)+=c-‘0‘;}
inline int lower(int x){
  int l=1,r=cb,mid,t=cb+1;
  while(l<=r)if(b[mid=(l+r)>>1]>=x)r=(t=mid)-1;else l=mid+1;
  return t;
}
inline void ins(int c,int V,int S){
  if(!c)return;
  int a=1,b=cb,x=1,mid;
  while(1){
    v[x]+=V,s[x]+=S;
    if(a==b)return;
    mid=(a+b)>>1,x<<=1;
    if(c<=mid)b=mid;else a=mid+1,x++;
  }
}
inline void ask(int c){
  int a=1,b=cb,x=1,mid;
  if(c>cb){cnt=0,sum=s[1];return;}
  cnt=v[1],sum=0;
  while(a<b){
    mid=(a+b)>>1,x<<=1;
    if(c<=mid)b=mid;else cnt-=v[x],sum+=s[x],a=mid+1,x++;
  }
}
int main(){
  read(n),read(m);
  for(i=1;i<=m;i++){
    char ch;
    while((ch=getchar())!=‘U‘&&ch!=‘Z‘);
    op[i][0]=ch,read(op[i][1]),read(op[i][2]);
    if(ch==‘U‘)b[++cb]=op[i][2];
  }
  std::sort(b+1,b+cb+1);
  for(i=1;i<=m;i++){
    x=op[i][1],y=op[i][2];
    if(op[i][0]==‘U‘){
      ins(a[x],-1,-b[a[x]]);
      a[x]=lower(y);
      ins(a[x],1,y);
    }else{
      ask(lower(y));
      puts(sum>=1LL*(x-cnt)*y?"TAK":"NIE");
    }
  }
  return 0;
}

  

时间: 2024-10-13 05:44:37

BZOJ4378 : [POI2015]Logistyka的相关文章

【BZOJ4378】[POI2015]Logistyka 树状数组

[BZOJ4378][POI2015]Logistyka Description 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作.每次询问独立,即每次询问不会对序列进行修改. Input 第一行包含两个正整数n,m(1<=n,m<=1000000),分别表示序列长度和操作次数.接下来m行为m个操作,其中1<=k,c<=n,0<=a<=

【BZOJ4378】[POI2015]Logistyka【树状数组】【结论题】

[题目链接] 题解: 首先得有一个结论:设个数大于s的数字有k个(如果k大于c,显然是TAK.这里讨论k <= c),那么如果个数小于s的数字和不小于(c - k) * s,那么一定有解. 并不会证明... 用树状数组记录一下数字的个数以及数字的数字和,然后判断就可以了. 复杂度: 时间复杂度:O(mlogm),空间复杂度:O(m). 1A. GET: 结论题... /* Telekinetic Forest Guard */ #include <cstdio> #include <

@bzoj - [email&#160;protected] [POI2015] Logistyka

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 维护一个长度为 n 的序列,一开始都是 0,支持以下两种操作: 1.U k a 将序列中第 k 个数修改为 a. 2.Z c s 在这个序列上,每次选出 c 个正数,并将它们都减去 1,询问能否进行 s 次操作. 每次询问独立,即每次询问不会对序列进行修改. input 第一行包含两个

待 题表

题表 达哥终极杂题表Bzoj2839 hdu6021 Codeforces 804DBzoj2248 hdu5575 Codeforces 786CBzoj2013 bzoj2676 Codeforces 803CBzoj2386 bzoj3782 Codeforces 813DBzoj2699 cogs1667 Codeforces 814DBzoj4798 bzoj2064 Codeforces 814EBzoj4639 bzoj3505 Codeforces 815ABzoj4417 bz

[Poi2015]

[POI2015]?asuchy 一看以为是sb题 简单来说就是每个人获得热量要尽量多 不能找别人 首先这道题好像我自己找不到NIE的情况 很容易想到一个优化 如果一个数/2>另一个数 那么一定选这个数 然后我想着其他的话就随便分配一个 然后会得出下一个 其实这样做是错的 因为你选完之后不知道下一个会不会是来降低我当前选的那一个的热量使得我当前的原来最优变成不是最优 然后这样子 怎么办呢??? 废话 膜题解 膜拜Claris 我们既然不知道下一个会不会来降低热量 不妨把每个食物的状态都定下来 让

bzoj 4385: [POI2015]Wilcze do?y

4385: [POI2015]Wilcze do?y Description 给定一个长度为n的序列,你有一次机会选中一段连续的长度不超过d的区间,将里面所有数字全部修改为0.请找到最长的一段连续区间,使得该区间内所有数字之和不超过p. Input 第一行包含三个整数n,p,d(1<=d<=n<=2000000,0<=p<=10^16).第二行包含n个正整数,依次表示序列中每个数w[i](1<=w[i]<=10^9). Output 包含一行一个正整数,即修改后能

BZOJ 3747: [POI2015]Kinoman( 线段树 )

线段树... 我们可以枚举左端点 , 然后用线段树找出所有右端点中的最大值 . ----------------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( i

poi2015 bzoj4377-4386训练

就按时间顺序写吧 完成度:8/10 3.30 bzoj4385 首先一定是删去连续d个数,然后枚举终点,起点显然有单调性,用单调队列乱搞搞就可以啦 bzoj4378 首先才结论:可行当且仅当把所有大于s的数全变成s然后看所有的数的和大于等于c*s,然后两个树状数组分别维护<=s的和及个数即可,注意需要离散化 3.31 bzoj4377 设一段的起点处的数为x,则m个限制条件就可以转化为x在若干个区间(或两个区间的并)里面,然后把这些区间交起来就得到了x的范围,算出个数然后减去最后m-1个数(没有

【BZOJ 3747】 3747: [POI2015]Kinoman (线段树)

3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 830  Solved: 338 Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l<=r<=n),并观看第l,l+1,-,r天内所有的电影.如果同一部电影你观看多于一次,你会感到无聊,于是无法获得这部电影的好看值