zoukankan      html  css  js  c++  java
  • Gym 101480G BZOJ 4432 [CERC2015]Greenhouse Growth (链表)

    题目链接

    (Gym) https://codeforces.com/gym/101480/standings
    (BZOJ) 大人,时代变了。

    题解

    很神仙的题。
    显然如果相邻两个数相等那么它们永远会相等,于是可以把相等的连续段缩到一起。
    用链表维护所有的连续段,并对每个连续段维护以下信息:
    (l),(r): 该连续段在原序列中对应的范围。
    (h),(t): 该连续段上次更新的时间为 (t)、在那时的高度为 (h).
    (fa),(fb): 发生 A/B 类操作时该连续段是否会增高。
    那么在不发生合并操作的前提下,时刻 (t_1) 该连续段的高度为 (h+fa(sa_{t_1}-sa_t)+fb(sb_{t_1}-sb_t)),其中 (sa_i,sb_i) 分别表示前 (i) 个时刻 A 和 B 操作的个数。

    对每一对相邻连续段,维护:
    (ga),(gb): 发生 A/B 类操作时,两个连续段高度的差距是否会缩小(缩小的幅度只能是 (0)(1))。
    并由此计算这两个连续段发生合并的时间,到时间的时候进行合并。
    每次合并时,先计算新连续段的相关数值,然后检验新连通块相邻的两个连通块,计算合并时间,挂到对应的时间上。

    时间复杂度 (O(n+m)).

    代码

    #include<bits/stdc++.h>
    #define llong long long
    #define mkpr make_pair
    #define x first
    #define y second
    #define iter iterator
    #define riter reverse_iterator
    #define y1 Lorem_ipsum_
    #define tm dolor_sit_amet_
    #define pii pair<int,int>
    using namespace std;
    
    inline int read()
    {
    	int x = 0,f = 1; char ch = getchar();
    	for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    	for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
    	return x*f;
    }
    
    const int mxN = 3e5;
    int n,q,tot,t;
    int h[mxN+3];
    char opt[mxN+3];
    int sa[mxN+3],sb[mxN+3],ta[mxN+3],tb[mxN+3];
    struct Node
    {
    	int prv,nxt,l,r,h,t,fa,fb,ga,gb; bool del;
    } li[mxN*2+3];
    queue<pii> que[mxN+3];
    
    void calch(int u)
    {
    	if(!u) return;
    	li[u].h += (sa[t]-sa[li[u].t])*li[u].fa+(sb[t]-sb[li[u].t])*li[u].fb;
    	li[u].t = t;
    }
    void calcg(int u)
    {
    	if(li[u].del||li[li[u].prv].del) return;
    	calch(u); calch(li[u].prv);
    	if(li[u].h==li[li[u].prv].h) {que[t].push(mkpr(u,li[u].prv)); return;}
    	li[u].ga = li[u].fa^li[li[u].prv].fa; li[u].gb = li[u].fb^li[li[u].prv].fb;
    	int x = abs(li[u].h-li[li[u].prv].h);
    	if(li[u].ga&&!li[u].gb) {if(sa[t]+x<=q) {que[ta[sa[t]+x]].push(mkpr(u,li[u].prv));}}
    	else if(!li[u].ga&&li[u].gb) {if(sb[t]+x<=q) {que[tb[sb[t]+x]].push(mkpr(u,li[u].prv));}}
    	else if(li[u].ga&&li[u].gb) {if(t+x<=q) {que[t+x].push(mkpr(u,li[u].prv));}}
    }
    void merge(int u,int v)
    {
    	if(li[u].del||li[v].del) return;
    	tot++; li[tot].prv = li[li[u].prv].prv,li[tot].nxt = li[u].nxt,li[li[tot].prv].nxt = tot,li[li[tot].nxt].prv = tot; li[li[u].prv].del = li[u].del = true;
    	calch(u); li[tot].h = li[u].h; li[tot].t = t; li[tot].l = li[li[u].prv].l,li[tot].r = li[u].r;
    	calch(li[tot].prv); calch(li[tot].nxt); li[tot].fa = (li[li[tot].prv].h>li[tot].h); li[tot].fb = (li[li[tot].nxt].h>li[tot].h);
    	if(li[tot].prv) {calcg(tot);} if(li[tot].nxt) {calcg(li[tot].nxt);}
    }
    
    int main()
    {
    	n = read(),q = read();
    	for(int i=1; i<=n; i++) h[i] = read();
    	scanf("%s",opt+1);
    	for(int i=1; i<=q; i++) {sa[i] = sa[i-1],sb[i] = sb[i-1]; if(opt[i]=='A') {sa[i]++; ta[sa[i]] = i;} else {sb[i]++; tb[sb[i]] = i;}}
    	for(int l=1; l<=n; l++)
    	{
    		int r = l; while(r<n&&h[r+1]==h[l]) {r++;}
    		tot++; li[tot-1].nxt = tot,li[tot].prv = tot-1;
    		li[tot].l = l,li[tot].r = r,li[tot].h = h[l],li[tot].t = 0; li[tot].fa = (h[l-1]>h[l]); li[tot].fb = (h[r+1]>h[r]);
    		l = r;
    	}
    	for(int i=li[li[0].nxt].nxt; i; i=li[i].nxt) {calcg(i);}
    	for(int i=1; i<=q; i++)
    	{
    		t = i;
    		while(!que[i].empty())
    		{
    			pii u = que[i].front(); que[i].pop();
    			merge(u.x,u.y);
    		}
    	}
    	for(int i=li[0].nxt; i; i=li[i].nxt)
    	{
    		calch(i);
    		for(int j=li[i].l; j<=li[i].r; j++) {printf("%d ",li[i].h);}
    	}
    	puts("");
    	return 0;
    }
    
  • 相关阅读:
    Sample XPS Documents Download
    触发器中的inserted表和deleted表
    Using freewheel.labs.autodesk.com to auto generate preview images of DWF files on your web site
    解除SQL对组件"Ad Hoc Distributed Queries"的"STATEMENT'OpenRowset OpenDatasource"的访问
    读写xps
    XPS文件,在Windows XP下的打开查看阅读和打印方法。
    Learning to Reference Inserted and Deleted Tables
    Get value from updated, inserted and deleted
    Reinstall Microsoft Helper Viewer
    如何查找文件的IFilter
  • 原文地址:https://www.cnblogs.com/suncongbo/p/14293489.html
Copyright © 2011-2022 走看看