zoukankan      html  css  js  c++  java
  • 2020-2021 ACM-ICPC, Asia Seoul Regional Contest 部分题目解答

    传送门
    https://codeforces.com/gym/102920

    B

    签到

    C

    题意:给出n个点,其中k个是特殊点,求有多少个点在特殊点两两连接的路径之间(特殊点自身也算)。
    分析:简单的树形DP。
    对于一个结点u,它被计入贡献当且仅当下面的条件中存在一条或多条满足:

    • 它的两棵子树上都有特殊点
    • 它的父节点有特殊点子节点有特殊点
    • 它本身是特殊点
    代码
    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define SET0(a) memset(a,0,sizeof(a))
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define DWN(i,a,b) for(int i=(a);i>=(b);i--)
    #define INF 0x3f3f3f3f
    typedef long long ll;
    
    const int N=1e5+5;
    struct node{
    	int to,next;
    }e[N<<1];
    int head[N],tot;
    void add(int u,int v){e[tot].to=v;e[tot].next=head[u];head[u]=tot++;}
    
    bool tag[N];
    int n,k;
    int ans=0;
    
    int dfs(int u,int fa){
    	 int res=0;
    	 if(tag[u]) res++;
    	 
    	 int cnt=0;
    	 for(int i=head[u];~i;i=e[i].next){
    	 	int go=e[i].to;
    	 	if(go==fa) continue;
    	 	int w=dfs(go,u);
    	 	if(w) cnt++;
    	 	res+=w;
    	 }
    	 if(res && res<=k-1 || tag[u] || cnt>=2) ans++;
    	 return res;
    }
    
    int main(){
    	memset(head,-1,sizeof head);
    	cin>>n>>k;
    	FOR(i,1,n-1){
    		int u,v,w; cin>>u>>v>>w;
    		add(u,v); add(v,u);
    	}	
    	
    	FOR(i,1,k){
    		int u; cin>>u;
    		tag[u]=1;
    	}
    
    	dfs(1,-1);
    	
    	cout<<ans<<endl;
    	
        return 0;
    }
    

    E

    分析:递推
    从最后一项开始分析,可以知道,最后一项只可能是0,1,而最后一项为1时,就是题目中的computer出了错误,我们可以对这个错误进行修正,那么
    需要修改的就是最后一项的前一项了。

    如何进行修正呢?

    修正意味着i与另一个数的胜负由它们的大小关系决定
    首先,我们考察项i:
    可知对于i,能够产生大小判断波动大只有i-1,i+1,故在这里只需考察i及i-1(因为i与i+1已经修正过了)(方便起见,我们将i比旁边的数记为,i比旁边的数记为
    i的胜场可以是0,1
    而胜场的差(f值)也可以是0,1

    具体修正方案:

    我们约定(x,y)意味着i的前后两次胜负情况,比如(0,1)的意思是有一次i胜了0场,有一次胜了1场

    而i+1项为1时(即f[i+1]=1,同时我们知道这意味着i项已经胜了一场),对此进行分类讨论:

    • f[i]=1时,i的两次胜负情况可能为(0,1) 因此在修正之后变为(0,0)
    • f[i]=0时,i的两次胜负情况可能为(1,1) 因此在修正之后变为(1,0)
    代码
    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define SET0(a) memset(a,0,sizeof(a))
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define DWN(i,a,b) for(int i=(a);i>=(b);i--)
    #define INF 0x3f3f3f3f
    typedef long long ll;
    
    const int N=1e6+5;
    int f[N];
    int n;
    
    int main(){
    	cin>>n;
    	FOR(i,1,n) cin>>f[i];
    	
    	bool ok=1;
    	DWN(i,n,1){
    		if(f[i]>=2 || f[i]<0){
    			ok=0;
    			break;
    		}
    		
    		if(f[i]==1) f[i-1]=(f[i-1]==0?1:f[i-1]-1);
    	}
    	
    	if(ok && !f[1]) puts("YES");
    	else puts("NO");
        return 0;
    }
    

    L

    题意:给定一个数组,求 (max((a[i]+a[j])(j-i)))
    分析:决策单调性分治

    代码
    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define SET0(a) memset(a,0,sizeof(a))
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define DWN(i,a,b) for(int i=(a);i>=(b);i--)
    #define INF 0x3f3f3f3f
    typedef long long ll;
    
    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*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    const int N=1e6+5;
    ll a[N];
    int n;
    
    int A1[N],A2[N];
    ll ans=-1;
    
    ll cal(int p1,int p2){
    	ll res=(A2[p2]-A1[p1])*(a[A2[p2]]+a[A1[p1]]);
    	return res;	
    }
    
    void solve(int l1,int r1,int l2,int r2){
    	if(l1>r1) return;
    	int mid=l1+r1>>1;
    	int pos=l2;
    	FOR(i,l2+1,r2)
    		if(cal(mid,pos)<cal(mid,i)) pos=i;
    	ans=ans>cal(mid,pos)?ans:cal(mid,pos);
    	solve(l1,mid-1,pos,r2); solve(mid+1,r1,l2,pos);
    }
    
    int main(){
    	cin>>n;
    	FOR(i,1,n) a[i]=read();
    	
    	int cnt1=0,cnt2=0;
    	A1[++cnt1]=1; A2[++cnt2]=n;
    	FOR(i,2,n)
    		if(a[i]>a[A1[cnt1]]) A1[++cnt1]=i;
    	DWN(i,n-1,1)
    		if(a[i]>a[A2[cnt2]]) A2[++cnt2]=i;
    	solve(1,cnt1,1,cnt2);
    	
    	cout<<ans<<endl;
    	
        return 0;
    }
    
    /* 
    加了快读 109 ms	15700 KB 
    不加TLE orz
    */
    
  • 相关阅读:
    Encryption (hard) CodeForces
    cf 1163D Mysterious Code (字符串, dp)
    AC日记——大整数的因子 openjudge 1.6 13
    AC日记——计算2的N次方 openjudge 1.6 12
    Ac日记——大整数减法 openjudge 1.6 11
    AC日记——大整数加法 openjudge 1.6 10
    AC日记——组合数问题 落谷 P2822 noip2016day2T1
    AC日记——向量点积计算 openjudge 1.6 09
    AC日记——石头剪刀布 openjudge 1.6 08
    AC日记——有趣的跳跃 openjudge 1.6 07
  • 原文地址:https://www.cnblogs.com/Tenshi/p/14447855.html
Copyright © 2011-2022 走看看