zoukankan      html  css  js  c++  java
  • HDU-4973-A simple simulation problem.(线段树)

    Problem Description
    There are n types of cells in the lab, numbered from 1 to n. These cells are put in a queue, the i-th cell belongs to type i. Each time I can use mitogen to double the cells in the interval [l, r]. For instance, the original queue is {1 2 3 3 4 5}, after using a mitogen in the interval [2, 5] the queue will be {1 2 2 3 3 3 3 4 4 5}. After some operations this queue could become very long, and I can’t figure out maximum count of cells of same type. Could you help me?
     

    Input
    The first line contains a single integer t (1 <= t <= 20), the number of test cases.

    For each case, the first line contains 2 integers (1 <= n,m<= 50000) indicating the number of cell types and the number of operations.

    For the following m lines, each line represents an operation. There are only two kinds of operations: Q and D. And the format is:

    “Q l r”, query the maximum number of cells of same type in the interval [l, r];
    “D l r”, double the cells in the interval [l, r];

    (0 <= r – l <= 10^8, 1 <= l, r <= the number of all the cells)
     

    Output
    For each case, output the case number as shown. Then for each query "Q l r", print the maximum number of cells of same type in the interval [l, r].

    Take the sample output for more details.
     

    Sample Input
    1 5 5 D 5 5 Q 5 6 D 2 3 D 1 2 Q 1 7
     

    Sample Output
    Case #1: 2 3
     

    Source
     

    思路:每次操作和查询前找区间端点相应的位置。分情况处理。


    #include <stdio.h>
    #define max(A,B)(A>B?

    A:B) long long sum[200005],att[200005],mx[200005],remain; void build(int idx,int s,int e) { if(s!=e) { int mid=(s+e)>>1; build(idx<<1,s,mid); build(idx<<1|1,mid+1,e); sum[idx]=sum[idx<<1]+sum[idx<<1|1]; } else sum[idx]=1; att[idx]=0; mx[idx]=1; } void segupdate(int idx,int s,int e,int l,int r) { if(s==l && r==e) { sum[idx]*=2; mx[idx]*=2; att[idx]++; return; } int mid=(s+e)>>1; if(att[idx]) { sum[idx<<1]<<=att[idx]; sum[idx<<1|1]<<=att[idx]; mx[idx<<1]<<=att[idx]; mx[idx<<1|1]<<=att[idx]; att[idx<<1]+=att[idx]; att[idx<<1|1]+=att[idx]; att[idx]=0; } if(r<=mid) segupdate(idx<<1,s,mid,l,r); else if(l>mid) segupdate(idx<<1|1,mid+1,e,l,r); else { segupdate(idx<<1,s,mid,l,mid); segupdate(idx<<1|1,mid+1,e,mid+1,r); } sum[idx]=sum[idx<<1]+sum[idx<<1|1]; mx[idx]=max(mx[idx<<1],mx[idx<<1|1]); } void update(int idx,int s,int e,int pos,int val) { if(s==e) { sum[idx]+=val; mx[idx]+=val; return; } if(att[idx]) { sum[idx<<1]<<=att[idx]; sum[idx<<1|1]<<=att[idx]; mx[idx<<1]<<=att[idx]; mx[idx<<1|1]<<=att[idx]; att[idx<<1]+=att[idx]; att[idx<<1|1]+=att[idx]; att[idx]=0; } int mid=(s+e)>>1; if(pos<=mid) update(idx<<1,s,mid,pos,val); else update(idx<<1|1,mid+1,e,pos,val); sum[idx]=sum[idx<<1]+sum[idx<<1|1]; mx[idx]=max(mx[idx<<1],mx[idx<<1|1]); } int query(int idx,int s,int e,long long val,bool flag) { if(s==e) { if(flag) remain=sum[idx]-val+1; else remain=val; return s; } if(att[idx]) { sum[idx<<1]<<=att[idx]; sum[idx<<1|1]<<=att[idx]; mx[idx<<1]<<=att[idx]; mx[idx<<1|1]<<=att[idx]; att[idx<<1]+=att[idx]; att[idx<<1|1]+=att[idx]; att[idx]=0; } int mid=(s+e)>>1; if(val<=sum[idx<<1]) return query(idx<<1,s,mid,val,flag); else return query(idx<<1|1,mid+1,e,val-sum[idx<<1],flag); } long long querymax(int idx,int s,int e,int l,int r) { if(s==l && e==r) return mx[idx]; if(att[idx]) { sum[idx<<1]<<=att[idx]; sum[idx<<1|1]<<=att[idx]; mx[idx<<1]<<=att[idx]; mx[idx<<1|1]<<=att[idx]; att[idx<<1]+=att[idx]; att[idx<<1|1]+=att[idx]; att[idx]=0; } int mid=(s+e)>>1; if(r<=mid) return querymax(idx<<1,s,mid,l,r); else if(l>mid) return querymax(idx<<1|1,mid+1,e,l,r); else { long long tempa=querymax(idx<<1,s,mid,l,mid); long long tempb=querymax(idx<<1|1,mid+1,e,mid+1,r); return max(tempa,tempb); } } int main() { int T,n,m,l,r,cases=1; long long a,b,ar,br,ans; char s[5]; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); printf("Case #%d: ",cases++); build(1,1,n); while(m--) { scanf("%s%I64d%I64d",s,&a,&b); if(s[0]=='D') { l=query(1,1,n,a,1); ar=remain; r=query(1,1,n,b,0); br=remain; if(l==r) update(1,1,n,l,b-a+1); else { update(1,1,n,l,ar); update(1,1,n,r,br); if(l+1<=r-1) segupdate(1,1,n,l+1,r-1); } } else { l=query(1,1,n,a,1); ar=remain; r=query(1,1,n,b,0); br=remain; if(l==r) printf("%I64d ",b-a+1); else { ans=max(ar,br); if(l+1<=r-1) ans=max(ans,querymax(1,1,n,l+1,r-1)); printf("%I64d ",ans); } } } } }



  • 相关阅读:
    leetcode 673. 最长递增子序列的个数 java
    leetcode 148. 排序链表 java
    leetcode 98. 验证二叉搜索树 java
    leetcode 29. 两数相除 java
    leetcode 234. 回文链表 java
    Valid Palindrome LeetCode Java
    Single Number II LeetCode Java
    Single Number LeetCode java
    Search in Rotated Sorted Array II LeetCode Java
    Search in Rotated Sorted Array leetcode java
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6871563.html
Copyright © 2011-2022 走看看