• Loj#3511【USACO 2021 Open, P】T1 United Cows of Farmer John


    【USACO 2021 Open, P】T1 United Cows of Farmer John

    题目链接

    题目大意

    (N)​ 头奶牛,每条队伍的队头和队尾都与队伍中其他牛的种类不同,还需选出队伍中的一个作为领队,也需与其他牛种类不同。

    求方案数。 (N le 2e5)

    解法

    将三个领队分别称作领头、领队和领尾。

    先不考虑领队。

    线段树维护两个值:区间内的 领头数量 和 领头和领尾匹配对数(领尾范围无限制)。

    具体是对于每次加入一个点,将对应 (b_i) 的上一个领头删掉,并使所有 (g_{l,r}+=f_{l,r}) ,将当前点记作新的领头。

    然后考虑对于一个领队位置为 (K),最长的有效区间设为 (left[ L, R ight]) ,用 做到R时(g_{L,K}) 减去做到K时 (g_{L,K}) 为答案。

    code

    #include<bits/stdc++.h>
    #define fo(i,a,b) for(int i=a;i<=b;++i)
    #define fd(i,a,b) for(int i=a;i>=b;--i)
    #define ll long long
    #define ls (t<<1)
    #define rs (t<<1|1)
    using namespace std;
    const ll N=2e5+10;
    ll n,a[N],ans,f[N<<2],g[N<<2],tag[N<<2];
    ll t[N],l[N],r[N],cnt,Ans[N];
    struct node{
    	ll t,v,l,r,id;
    }b[N*2];
    bool cmp(node a,node b){return a.t<b.t;}
    void push(ll t){
    	g[ls]+=f[ls]*tag[t];
    	g[rs]+=f[rs]*tag[t];
    	tag[ls]+=tag[t];tag[rs]+=tag[t];
    	tag[t]=0;
    }
    void add(ll t,ll l,ll r,ll L,ll R){
    	if(L<=l && r<=R){
    		g[t]+=f[t];
    		++tag[t];
    		return;
    	}
    	ll mid=l+r>>1;
    	if(L<=mid)add(ls,l,mid,L,R);
    	if(R>mid)add(rs,mid+1,r,L,R);
    	g[t]=g[ls]+g[rs];
    }
    void modify(ll t,ll l,ll r,ll x,ll y){
    	f[t]+=y;
    	if(l==r)return;
    	if(tag[t])push(t);
    	ll mid=l+r>>1;
    	if(x>mid)modify(rs,mid+1,r,x,y);
    	else modify(ls,l,mid,x,y);
    }
    ll query(ll t,ll l,ll r,ll L,ll R){
    	if(L<=l && r<=R)return g[t];
    	if(tag[t])push(t);
    	ll mid=l+r>>1,ret=0;
    	if(L<=mid)ret+=query(ls,l,mid,L,R);
    	if(R>mid)ret+=query(rs,mid+1,r,L,R);
    	return ret;
    }
    int main(){
    	scanf("%lld",&n);
    	fo(i,1,n){
    		scanf("%lld",&a[i]);
    		l[i]=t[a[i]];
    		t[a[i]]=i;
    	}
    	fo(i,1,n)t[i]=n+1;
    	fd(i,n,1){
    		r[i]=t[a[i]];
    		t[a[i]]=i;
    	}
    	fo(i,2,n-1){
    		ll L=l[i]+1,R=r[i]-1;
    		if(L<i && i<R){
    			b[++cnt]=(node){i,-1,L,i-1,i};
    			b[++cnt]=(node){R,1,L,i-1,i};
    		}
    	}
    	sort(b+1,b+cnt+1,cmp);
    	for(ll i=1,it=1;i<=cnt && it<=cnt;++i){
    		if(l[i])modify(1,1,n,l[i],-1);
    		if(l[i]+1<i)add(1,1,n,l[i]+1,i-1);
    		modify(1,1,n,i,1);
    		for(;it<=cnt && b[it].t==i;++it){
    			ans+=b[it].v*query(1,1,n,b[it].l,b[it].r);
    			Ans[b[it].id]+=b[it].v*query(1,1,n,b[it].l,b[it].r);
    		}
    	}
    	printf("%lld
    ",ans);
    //	fo(i,1,n)printf("%lld ",Ans[i]);
    //	printf("
    ");
    	
    	return 0;
    }
    
  • 相关阅读:
    自考新教材-p173_3(1)
    自考新教材-p148_5(2)
    自考新教材-p148_5(1)
    自考新教材-p148_4
    自考新教材-p147_3
    自考新教材-p146_4(2)
    python 模块 chardet报错解决方法:下载及介绍
    第 52 讲:论一只爬虫的自我修养
    第 51 讲: _name_属性
    Python 培训第一讲
  • 原文地址:https://www.cnblogs.com/Kelvin2005/p/15163761.html
Copyright © 2020-2023  润新知