[USACO17DEC]Milk Measurement(平衡树)

题意

最初,农夫约翰的每头奶牛每天生产G加仑的牛奶 (1≤G≤109)(1≤G≤10^9)(1G109) 。由于随着时间的推移,奶牛的产奶量可能会发生变化,农夫约翰决定定期对奶牛的产奶量进行测量,并将其记录在日志中。

他的日志中的记录如下:

35 1234 -2

14 2345 +3

第一个条目表明:在第35天,1234号奶牛的产奶量比上次测量时降低了2加仑。

第二个条目表明:在第14天,2345号奶牛的产奶量比上次测量时增加了3加仑。

农夫约翰只有在任何一天内做最多一次测量的时间(即每天最多做一次测量,但可能不做)。不幸的是,约翰有点杂乱无章,他不一定按照时间顺序记下测量结果。为了保持奶牛的产奶动力,农夫约翰自豪地在谷仓的墙上展示了目前产奶量最高的奶牛的照片(如果有若干头奶牛的产奶量最高,他就会展示所有的图片)。

请求出约翰需要调整所展示的照片的次数。

请注意,农夫约翰有一大群奶牛。所以尽管日志中记录了一些奶牛改变了产奶量,但仍然还有很多奶牛的产奶量保持在G加仑。

题解

每一个时间只有一个奶牛产奶量会变化。

我们算出变化前的产奶量的排名,和变化后的产奶量排名。

如果发现是从第一变到不是第一,或从不是第一到第一,那照片一定发生变化。

如果变化后,和变化前都是第一。照片可能变也可能不会变,分四种情况讨论:
1,、可能一开始有很多奶牛并列第一,然后其中的一个奶牛独占了第一。这时照片会变。

2、一开始一个奶牛是第一,然后产奶量增加还是第一,显然不变。

3、也有可能开始一个奶牛第一然后,产奶量下降,变得和第二一样,这时会变。

4、一开始一个奶牛是第一,然后产奶量下降但比第二高还是第一,显然不变。

所以我们找出产奶量为变化之前的奶牛的数量,和产奶量为变化之后的奶牛的数量,判断相不相等即可。

这些东西都可以用平衡树维护。(权值线段树,主席树什么的当然也可以)

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<map> 
  7 using namespace std;
  8 const int N=500010;
  9 map<int,int>ma;
 10 int n,g,mx,num;
 11 int a[N],b[N],ans[N];
 12 int cnt[N],size[N],ch[N][2],fa[N],v[N];
 13 int root,tot;
 14 struct hhh{
 15     int t,id,w;
 16 }c[N];
 17 bool cmp(hhh a,hhh b){
 18     return a.t<b.t;
 19 }
 20 void update(int x){
 21     size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];
 22 }
 23 int son(int x){
 24     return x==ch[fa[x]][1];
 25 }
 26 void rotate(int x){
 27     int y=fa[x],z=fa[y],a=son(x),b=son(y),c=ch[x][!a];
 28     if(z)ch[z][b]=x;
 29     else root=x;
 30     fa[x]=z;
 31     if(c)fa[c]=y;
 32     ch[x][!a]=y;
 33     ch[y][a]=c;
 34     fa[y]=x;
 35     update(y);
 36     update(x);
 37 }
 38 void splay(int x,int f){
 39     while(fa[x]!=f){
 40         int y=fa[x];
 41         int z=fa[y];
 42         if(z==f)rotate(x);
 43         else{
 44             if(son(y)==son(x))rotate(y);
 45             else rotate(x);
 46             rotate(x);
 47         }
 48     }
 49     if(f==0)root=x;
 50 }
 51 void ins(int x){
 52     int p=root;
 53     int f=0;
 54     while(p&&v[p]!=x){
 55         f=p;
 56         size[p]++;
 57         p=ch[p][v[p]<x];
 58     }
 59     if(p){
 60         size[p]++;
 61         cnt[p]++;
 62     }
 63     else{
 64         p=++tot;
 65         if(f)ch[f][v[f]<x]=p;
 66         size[p]=cnt[p]=1;
 67         v[p]=x;
 68         fa[p]=f;
 69     }
 70     splay(p,0); 
 71 }
 72 int getmn(int rt){
 73     int p=rt,ans=-1;
 74     while(p){
 75         ans=p;
 76         p=ch[p][0];
 77     }
 78     return ans;
 79 }
 80 
 81 void del(int rt,int x){
 82     if(v[rt]==x){
 83         if(cnt[rt]>1)cnt[rt]--,size[rt]--;
 84         else{
 85             splay(rt,0);
 86             int p=getmn(ch[rt][1]);
 87             if(p!=-1){
 88                 splay(p,rt);
 89                 root=p;
 90                 fa[p]=0;
 91                 ch[p][0]=ch[rt][0];
 92                 fa[ch[rt][0]]=p;
 93                 update(p);
 94             }
 95             else {
 96                 root=ch[rt][0];
 97                 fa[root]=0;
 98             }
 99         }
100         return;
101     }
102     if(x<v[rt])del(ch[rt][0],x),update(rt);
103     else del(ch[rt][1],x),update(rt);
104 }
105 int rank(int rt,int k){
106     if(v[rt]==k){
107         splay(rt,0);
108         return size[ch[rt][1]]+1;
109     }
110     if(k<v[rt])return rank(ch[rt][0],k);
111     else return rank(ch[rt][1],k);
112 }
113 int getsame(int rt,int x){
114     if(v[rt]==x){
115         splay(rt,0);
116         return cnt[rt];
117     }
118     if(x<v[rt])return rank(ch[rt][0],x);
119     else return rank(ch[rt][1],x);
120 }
121 int main(){
122     scanf("%d%d",&n,&g);
123     for(int i=1;i<=n;i++){
124         scanf("%d%d",&c[i].t,&c[i].id);
125         char ch;
126         cin>>ch;
127         scanf("%d",&c[i].w);
128         if(ch=='-')c[i].w=-c[i].w;
129         b[i]=c[i].id;
130     }
131     sort(b+1,b+1+n);
132     int cnt=unique(b+1,b+1+n)-b-1;
133     for(int i=1;i<=n;i++){
134         c[i].id=lower_bound(b+1,b+1+cnt,c[i].id)-b;
135     }
136     sort(c+1,c+1+n,cmp);
137     for(int i=1;i<=cnt+1;i++){
138         a[i]=g;
139         ins(g);
140     }
141     ma[g]=cnt+1;
142     for(int i=1;i<=n;i++){
143     //    cout<<";asjhfljashfjashdfasdf"<<endl;
144         if(c[i].w==0)continue;
145         int k=rank(root,a[c[i].id]);
146         int num1=getsame(root,a[c[i].id]);
147     //    cout<<k<<" "<<num1<<endl<<"aaa"<<endl;
148         del(root,a[c[i].id]);
149         a[c[i].id]+=c[i].w;
150         ins(a[c[i].id]);
151         int kk=rank(root,a[c[i].id]); 
152         int num2=getsame(root,a[c[i].id]);
153         if((kk==1&&k!=1)||(k==1&&kk!=1)||(num1!=num2&&kk==1&&k==1)){
154             ans[++num]=c[i].t;
155         }
156     }
157     printf("%d\n",num);
158 //    for(int i=1;i<=num;i++){
159 //        printf("%d\n",ans[i]);
160 //    }
161     return 0;
162 }
163 /*
164 4 10
165 7 3 +3
166 4 2 -1
167 9 3 -1
168 1 1 +2
169 */
posted @ 2018-08-24 14:26  Xu-daxia  阅读(447)  评论(0编辑  收藏  举报