题解:

每一次最短的那块板合并

先装水到溢出

然后合并

代码:

#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<vector>  
using namespace std;  
typedef pair<int,int> mp;
const int N=1000005;  
vector<mp> vec;
int LH[N],RH[N],L[N],R[N],O[N],X[N],heap[N],l[N],r[N],dist[N];
int T,kase,v[N],f[N],tot,n,m,x,y,z;
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}  
int merge(int x,int y)
{
    if (!x||!y)return x+y;
    if (v[x]>v[y])swap(x,y);
    r[x]=merge(r[x],y);
    if (dist[l[x]]<dist[r[x]])swap(l[x],r[x]);
    dist[x]=dist[r[x]]+1;
    return x;
}
void Union(int x,int y)
{  
    x=find(x);y=find(y);  
    if (x==y)return;  
    f[y]=x;  
    if (x<y)
     {  
        RH[x]=RH[y];  
        L[R[x]]=x;  
        R[x]=R[y];  
     }  
    else
     {  
        LH[x]=LH[y];  
        R[L[x]]=x;  
        L[x]=L[y];  
     }  
    heap[x]=merge(heap[x],heap[y]);  
    X[x]+=X[y];  
    O[x]+=O[y];  
}  
int pop(int x){return merge(l[x],r[x]);}  
int main()
{  
    scanf("%d",&T);  
    while(T--)
     {   
        scanf("%d%d",&n,&m);  
        int ans=0;LH[1]=RH[n]=1e9;L[n]=n-1;  
        for (int i=1;i<n;i++)
         {  
            scanf("%d",&RH[i]);  
            LH[i+1]=RH[i];  
            L[i]=i-1;R[i]=i+1;  
         }  
        vec.clear();  
        memset(heap,0,sizeof(heap));  
        tot=0;  
        while(m--)
         {  
            scanf("%d%d%d",&x,&y,&z);  
            if (z)vec.push_back(mp(y+1,x));   
            else
             {  
                ++ans;  
                v[++tot]=y;  
                l[tot]=r[tot]=dist[tot]=0;  
                heap[x]=heap[x]?merge(heap[x],tot):tot;  
             }  
         }   
        for (int i=1;i<=n;i++) f[i]=i;  
        sort(vec.begin(),vec.end());  
        for (int i=1;i<=n;i++) O[i]=X[i]=0;  
        for (int i=0;i<vec.size();i++)
         {  
            int x=find(vec[i].second),y=vec[i].first;  
            while(y>LH[x])Union(x,L[x]),x=find(x);    
            while(y>RH[x])Union(x,R[x]),x=find(x);
            while(heap[x]!=0&&v[heap[x]]<y)
             {  
                heap[x]=pop(heap[x]);  
                ++X[x];  
             }  
            if (++O[x]>=X[x])
             {  
                ans+=(O[x]-X[x]);  
                O[x]=X[x]=0;  
             }  
         }  
        printf("Case #%d: %d\n",++kase,ans);  
     }  
}  

 

posted on 2017-12-23 14:47  宣毅鸣  阅读(288)  评论(0编辑  收藏  举报