zoukankan      html  css  js  c++  java
  • [bzoj4378] [POI2015]Logistyka

      离线+树状数组。。

      对于某个询问(S次,每次选出C个数),数列中每个数最多被减S次,只要判断(C- (数列中>=S的数个数))*S是否小于等于(数列中<S的数的和)就好了。

      或者说。。把数列中>=S的数都变成S后,求一下总和是否大于等于S*C。。。

      因为数字可能很大所以离线后hash一发。

      网上的奇怪证明都是什么鬼。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll long long
     6 using namespace std;
     7 const int maxn=1000233;
     8 struct zs{
     9     int id,v;
    10 }b[maxn];int cnt;
    11 struct ask{
    12     bool id;int x,y;
    13 }q[maxn];
    14 int mp[maxn],t[maxn],c[maxn];
    15 ll sm[maxn],sum;
    16 int i,j,k,n,m,num;
    17  
    18 int ra;char rx;
    19 inline int read(){
    20     rx=getchar(),ra=0;
    21     while(rx<'0'||rx>'9')rx=getchar();
    22     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    23 }
    24 inline void add(int x){
    25 //  printf("add %d
    ",x);
    26     for(int i=x;i<=cnt;i+=i&-i)t[i]++,sm[i]+=c[x];
    27 }
    28 inline void del(int x){
    29     for(int i=x;i<=cnt;i+=i&-i)t[i]--,sm[i]-=c[x];
    30 }
    31 inline void query(int x,int &num,ll &sum){
    32     num=sum=0;
    33     for(int i=x;i;i-=i&-i)num+=t[i],sum+=sm[i];
    34 }
    35  
    36  
    37 bool cmp(zs a,zs b){return a.v<b.v;}
    38 int main(){
    39     n=read(),m=read();char id;
    40     for(i=1;i<=m;i++){
    41         for(id=getchar();id<'A'||id>'Z';id=getchar());
    42         q[i].id=id=='U';
    43         if(id=='U')q[i].x=read(),q[i].y=read();
    44         else q[i].x=read(),q[i].y=read();
    45         b[i].v=q[i].y,b[i].id=i;
    46     }
    47     sort(b+1,b+1+m,cmp);
    48     for(i=1;i<=m;i++){
    49         if(b[i].v!=b[i-1].v||i==1)c[++cnt]=b[i].v;
    50         q[b[i].id].y=cnt;
    51     }
    52     int n1=0;
    53     for(i=1;i<=m;i++){
    54 //      printf("%d  %d %d
    ",q[i].id,q[i].x,q[i].y);
    55         if(q[i].id){
    56         //  all-=c[mp[q[i].x]],all+=c[q[i].y];
    57             if(mp[q[i].x])del(mp[q[i].x]);else n1++;
    58             add(q[i].y),mp[q[i].x]=q[i].y;
    59         }else{
    60             query(q[i].y,num,sum);num=n1-num;//printf("number>=%d:%d    rest:%lld
    ",c[q[i].y],num,sum);
    61             if(sum>=(ll)c[q[i].y]*(q[i].x-num))puts("TAK");else puts("NIE");
    62         }
    63     }
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    单例模式
    关于static
    在O(1)时间复杂度删除链表节点
    奇偶分割数组
    用栈实现队列
    前序遍历和中序遍历树构造二叉树
    扇贝每日一句_1006
    寻找旋转排序数组中的最小值
    翻转链表
    扇贝每日一句_1002
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5310956.html
Copyright © 2011-2022 走看看