zoukankan      html  css  js  c++  java
  • 【AtCoder】 ARC 098

    C-Attention

    题意:一个字符队列,每个位置是(W)(E),计算最小的修改数量,使得存在一个位置,它之前的都是(E),之后的都是(F)

    #include<bits/stdc++.h>
    #define ll long long
    #define dbg1(x) cerr<<#x<<"="<<(x)<<" "
    #define dbg2(x) cerr<<#x<<"="<<(x)<<"
    "
    #define dbg3(x) cerr<<#x<<"
    "
    using namespace std;
    #define reg register
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    const int MN=3e5+5;
    int ans,tmp;
    char s[MN];
    int main()
    {
    	int i,N=read();
    	scanf("%s",s+1);
    	for(i=1;i<N;++i)tmp+=s[i]=='W';ans=tmp;
    	for(i=N-1;i;--i)tmp+=s[i+1]=='E',tmp-=s[i]=='W',ans=min(ans,tmp);
    	printf("%d
    ",ans);
    }
    

    D-Xor Sum 2

    题意:给出一个序列,问有多少个区间满足区间异或和等于区间和

    发现满足若大区间满足,则内部区间都满足,采用尺取法即可。

    #include<bits/stdc++.h>
    #define ll long long
    #define dbg1(x) cerr<<#x<<"="<<(x)<<" "
    #define dbg2(x) cerr<<#x<<"="<<(x)<<"
    "
    #define dbg3(x) cerr<<#x<<"
    "
    using namespace std;
    #define reg register
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    const int MN=2e5+5;
    int N,a[MN],Xor,Sum;
    ll ans;
    int main()
    {
    	N=read();
    	reg int i,l,r;
    	for(i=1;i<=N;++i) a[i]=read();
    	for(l=1,r=1;l<=N;++l)
    	{
    		while((Xor^a[r])==(Sum+a[r])&&r<=N)
    			Xor^=a[r],Sum+=a[r++];
    		ans+=r-l;
    		Xor^=a[l];Sum-=a[l];
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    



    E-Range Minimum Queries

    题意:长度为(N)的序列,每次选一个长度为(K)的区间,删除任意一个最小的数,共执行(Q)次,问删除的数的最小极差

    可以枚举最小删除的数,然后显然整个序列变成一个个可执行区间,从小到达删除可以删除的数,直到所有可执行的区间长度小于(K),或恰好删了(Q)个数。

    #include<bits/stdc++.h>
    #define ll long long
    #define dbg1(x) cerr<<#x<<"="<<(x)<<" "
    #define dbg2(x) cerr<<#x<<"="<<(x)<<"
    "
    #define dbg3(x) cerr<<#x<<"
    "
    using namespace std;
    #define reg register
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    const int MN=2005,inf=1e9+5;
    int N,K,Q;
    int id[MN],a[MN];
    bool cmp(int x,int y){return a[x]<a[y];}
    int bel[MN],len[MN],cnt,bl;bool in[MN];
    int solve(int pos)
    {
    	memset(in,0,sizeof in);
    	cnt=bl=0;reg int i,j,k;
    	for(i=1;i<=N;++i)
    	{
    		for(;i<=N&&a[i]<a[pos];++i);
    		for(j=i;j<=N&&a[j]>=a[pos];++j);--j;//因为--j Wa了5次
    		for(len[++bl]=j-i+1,k=i;k<=j;++k)
    			bel[k]=bl,in[k]=true;
    		i=j;
    	}
    	for(i=1;i<=N;++i)if(in[id[i]]&&len[bel[id[i]]]>=K)
    	{
    		--len[bel[id[i]]];
    		if(++cnt==Q)return a[id[i]]-a[pos];
    	}
    	return inf;
    }
    int main()
    {
    	N=read();K=read();Q=read();
    	reg int i;
    	for(i=1;i<=N;++i)a[id[i]=i]=read();
    	sort(id+1,id+N+1,cmp);
    	int ans=inf;
    	for(i=1;i<=N;++i) ans=min(ans,solve(i));
    	return 0*printf("%d
    ",ans);
    }
    



    F-Donation

    题意:一张简单图,每个点有两个值(A_i,B_i),一开始你有(W)yen,选择一个点满足(A_s<W)作为起始点,每次可以执行两种操作,移动到相邻的(i)点上去(满足(A_i<W)),或是对当前点捐赠(B_i)yen((W-=B_i,Wgeq 0)),求可以对每个点都恰好捐赠一次的最小(W)

    (搬来的)题解:

    我们将题目关于(Wgeq A_i)的限制更改为经过一个点之后需满足(Wgeq Max(A_i-B_i,0)),并且一定是在最后一次经过某个点的时候才对这个点进行捐赠

    证明:

    1. 如果对这个点进行了捐赠,那么捐赠前(Wgeq Max(A_i-B_i,0)+B_igeq A_i)

    2. 如果没有对这个点进行捐赠,那么之后肯定会对这个点进行捐赠,因为满足每一时刻的限制,所以当前的(Wgeq A_i)

    3. 关于“一定是在最后一次经过某个点的时候才对这个点进行捐赠”,因为我们可以延迟捐赠,这样对之后的操作无影响,并且对于之前时刻的(W)有增无减

    我们可以设(C_i=Max(A_i-B_i,0))

    转化条件后,我们走到第(k)步(移动第(k)次)到达点(id_k)需要满足的是:

    (Wgeq SumB_k+C_{id_k}),其中(SumB)表示之前已经捐赠的钱的总和

    所以(Wgeq Max_k{ SumB_k,C_{id_k}})

    我们考虑最大的(C_i),删除这个点之后,会使得原图裂成几个联通块(G_1,G_2,..G_n),优秀的做法一定是先访问了所有的(G_i(i eq k)),然后在访问(G_k),因为如果先访问了(G_k)中的某个点,一定会增大点(i)的要求下限值,而对(G_k)内的点的要求值无影响

    所以我们可以类似的一次处理每个(G_i)内的点

    具体的,可以建一棵树,满足每个节点是其子树所代表的联通块中(C_i)最大的

    建树的过程可以对(C_i)从小到大排序,依次枚举每个点,将其相邻的并且根的(C_i)比当前小的树合并作为它的子树,这个过程需要用并查集维护每个点所在树的根

    注意(C_i)可能相同,所以对于(C_i)的比较应该选用排序后的(rank)

    补:最后如和求答案?

    答:建出树后在树上(Dp)即可,显然访问根之前的都没有用,因为根的(C_i)(SumB)都是最大的,所以对于当前子树,假设根为(x),枚举最后一个访问的联通块,答案就是(dp[x]=Min{ siz[x]-siz[y]+Max(C_x,dp_y)})。叶子节点特殊处理(dp_x=B_x+C_x)

    没有路径压缩(TLE)了好几次

    ps:哇哇哇我怎么写得这么认真。。。

    #include<bits/stdc++.h>
    #define ll long long
    #define dbg1(x) cerr<<#x<<"="<<(x)<<" "
    #define dbg2(x) cerr<<#x<<"="<<(x)<<"
    "
    #define dbg3(x) cerr<<#x<<"
    "
    using namespace std;
    #define reg register
    #define pb push_back
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
    const int MN=1e5+5;
    int N,M,id[MN],rk[MN],par[MN];
    ll f[MN],sz[MN],A[MN],B[MN],C[MN];
    vector<int> G[MN],T[MN];
    bool cmp(const int&x,const int&y){return C[x]<C[y];}
    int getf(int x){return x==par[x]?x:par[x]=getf(par[x]);}
    void rw(ll &x,ll y){if(y<x)x=y;}
    void dfs(int x)
    {
    	#define y T[x][i]
    	reg int i;sz[x]=B[x];f[x]=1e15;
    	if(!T[x].size())return (void)(f[x]=B[x]+C[x]);
    	for(i=T[x].size()-1;~i;--i)dfs(y),sz[x]+=sz[y];
    	for(i=T[x].size()-1;~i;--i)rw(f[x],sz[x]-sz[y]+max(C[x],f[y]));
    	#undef y
    }
    int main()
    {
    	N=read();M=read();
    	reg int i,j,x,y;
    	for(i=1;i<=N;++i) par[i]=id[i]=i;
    	for(i=1;i<=N;++i) A[i]=read(),B[i]=read(),C[i]=max(A[i]-B[i],0LL);
    	for(i=1;i<=M;++i) x=read(),y=read(),G[x].pb(y),G[y].pb(x);
    	sort(id+1,id+N+1,cmp);
    	for(i=1;i<=N;++i)rk[id[i]]=i;
    	for(i=1;i<=N;++i)for(j=G[x=id[i]].size()-1;~j;--j)
    	{
    		y=getf(G[x][j]);
    		if(y!=x&&rk[y]<i) par[y]=x,T[x].pb(y);
    	}
    	dfs(id[N]);
    	return 0*printf("%lld
    ",f[id[N]]);
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    PC上图标显示异常 白色框框处理方案
    判断Javascript变量是否为空 undefined 或者null(附样例)
    MySQL双版本共存解决方案
    跨境电商进口业务的通关模式
    史上最完整跨境电商投资分析报告!
    Fastcgi_Finish_Request 提高页面响应速度
    浏览器工作原理
    thinkphp 命名规范
    git diff ^M的消除
    git简明教程
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/11437023.html
Copyright © 2011-2022 走看看