zoukankan      html  css  js  c++  java
  • Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) 题解

    借了某神仙的号来打Div2,结果手速过C之后莽了个错误结论。好不容易把结论改对了结果喜闻乐见被DDos攻击了?(上次DDos好像也是Technocup吧)

    之后就果断颓废了

    A

    特判2,之后奇数答案为1,偶数答案为0

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    const int N=10000;
    const db pi=acos(-1.0);
    #define lowbit(x) (x)&(-x)
    #define sqr(x) (x)*(x)
    #define rep(i,a,b) for (register int i=a;i<=b;i++)
    #define per(i,a,b) for (register int i=a;i>=b;i--)
    #define fir first
    #define sec second
    #define mp(a,b) make_pair(a,b)
    #define pb(a) push_back(a)
    #define maxd 998244353
    #define eps 1e-8
    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;
    }
    
    int main()
    {
    	int q=read();
    	while (q--)
    	{
    		int n=read();
    		if (n==2) puts("2");
    		else if (n&1) printf("%d
    ",1);
    		else puts("0");
    	}
    	return 0;
    }
    

    B

    不难发现你可以把一个字符串统一成只由一个原串中出现的字母,然后就变成了判断两个字符串是否有相同字符了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    const int N=10000;
    const db pi=acos(-1.0);
    #define lowbit(x) (x)&(-x)
    #define sqr(x) (x)*(x)
    #define rep(i,a,b) for (register int i=a;i<=b;i++)
    #define per(i,a,b) for (register int i=a;i>=b;i--)
    #define fir first
    #define sec second
    #define mp(a,b) make_pair(a,b)
    #define pb(a) push_back(a)
    #define maxd 998244353
    #define eps 1e-8
    int n,tax[40];
    char s[1010],t[1010];
    
    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;
    }
    
    int main()
    {
    	int q=read();
    	while (q--)
    	{
    		scanf("%s",s+1);
    		scanf("%s",t+1);
    		n=strlen(s+1);
    		rep(i,1,n) tax[s[i]-'a']=1;
    		int ok=0;
    		rep(i,1,n)
    			if (tax[t[i]-'a']) {ok=1;break;}
    		if (ok) puts("YES");else puts("NO");
    		rep(i,0,26) tax[i]=0;
    	}
    	return 0;
    } 
    

    C

    答案具有二分性于是考虑二分答案。预处理每一个位置对捐赠值的贡献,二分所需天数,暴力贪心填就可以了,时间复杂度貌似被写成了(O(qnlog^2n)),似乎可以1个(log)(但是能过还管他干嘛)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    const int N=10000;
    const db pi=acos(-1.0);
    #define int long long
    #define lowbit(x) (x)&(-x)
    #define sqr(x) (x)*(x)
    #define rep(i,a,b) for (register int i=a;i<=b;i++)
    #define per(i,a,b) for (register int i=a;i>=b;i--)
    #define fir first
    #define sec second
    #define mp(a,b) make_pair(a,b)
    #define pb(a) push_back(a)
    #define maxd 998244353
    #define eps 1e-8
    int n,a[200200],pri[200200],p[200200],lim,tmp[200200];
    
    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;
    }
    
    bool chk(int len)
    {
    	rep(i,1,len) tmp[i]=a[i];
    	sort(tmp+1,tmp+1+len);
    	reverse(tmp+1,tmp+1+len);
    	ll ans=0;
    	rep(i,1,len)
    	{
    		ans+=pri[i]*tmp[i];
    		if (ans>=lim) return 1;
    	}
    	return 0;
    }
    
    
    signed main()
    {
    	int q=read();
    	while (q--)
    	{
    		n=read();
    		rep(i,1,n) pri[i]=read()/100;
    		sort(pri+1,pri+1+n);
    		reverse(pri+1,pri+1+n);
    		rep(i,1,n) a[i]=0;
    		int pro1=read(),gap=read();
    		for (int i=gap;i<=n;i+=gap) a[i]+=pro1;
    		pro1=read();gap=read();
    		for (int i=gap;i<=n;i+=gap) a[i]+=pro1;
    		lim=read();int l=1,r=n,ans=-1;
    		while (l<=r)
    		{
    			int mid=(l+r)>>1;
    			if (chk(mid)) {ans=mid;r=mid-1;}
    			else l=mid+1;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    D

    直接考虑哪些数字进行了操作比较麻烦,我们考虑那些没有进行的操作的数字,最后用总数字种类数减一下

    不难发现未被操作的数字从小到大排序后一定是一段区间,这个用反证法就比较显然。之后就可以直接dp以(i)结尾的最长不操作的区间长度,判一下前一个数字的区间是否合法就可以了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    const int N=10000;
    const db pi=acos(-1.0);
    #define lowbit(x) (x)&(-x)
    #define sqr(x) (x)*(x)
    #define rep(i,a,b) for (register int i=a;i<=b;i++)
    #define per(i,a,b) for (register int i=a;i>=b;i--)
    #define fir first
    #define sec second
    #define mp(a,b) make_pair(a,b)
    #define pb(a) push_back(a)
    #define maxd 998244353
    #define eps 1e-8
    int n,a[300100],x[300300],m,f[300300],l[300300],r[300300];
    
    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;
    }
    
    int main()
    {
    	int q=read();
    	while (q--)
    	{
    		n=read();
    		rep(i,1,n) x[i]=a[i]=read();
    		rep(i,0,n) {l[i]=maxd;r[i]=0;}
    		rep(i,1,n)
    		{
    			l[a[i]]=min(l[a[i]],i);
    			r[a[i]]=max(r[a[i]],i);
    		}
    		sort(x+1,x+1+n);
    		m=unique(x+1,x+1+n)-x-1;
    		rep(i,1,m)
    			if (l[x[i]]>r[x[i-1]]) f[i]=f[i-1]+1;
    			else f[i]=1;
    		int ans=0;
    		rep(i,1,m) ans=max(ans,f[i]);
    		printf("%d
    ",m-ans);
    	}
    	return 0;
    }
    

    E

    感觉这个题就十分的套路

    (f_{i.0/1})表示(i)不能/能向上时,其子树的最大价值和。转移的话考虑所有的儿子是否往上连。记(f_{v,1}+w>f_{v,0})的点为好点。好点个数(<k)时直接暴力转移(max(f_{v,0}+w,f_{v,1}))

    否则我们需要选择最优的(k-1)(f_{v,1}+w)进行转移,随便移个项得到可以将(f_{v,1}+w-f_{v,0})的值从大到小,前(k-1)大的儿子考虑向上走,对第(k)大的分类讨论,最后处理剩下的儿子。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    const int N=10000;
    const db pi=acos(-1.0);
    #define lowbit(x) (x)&(-x)
    #define sqr(x) (x)*(x)
    #define rep(i,a,b) for (register int i=a;i<=b;i++)
    #define per(i,a,b) for (register int i=a;i>=b;i--)
    #define fir first
    #define sec second
    #define mp(a,b) make_pair(a,b)
    #define pb(a) push_back(a)
    #define maxd 998244353
    #define eps 1e-8
    struct node{int to,nxt,cost;}sq[1001000];
    int all=0,head[500500];
    int n,k,tot=0;
    ll f[500500][2];
    pii son[500500];
    bool cmp(pii p,pii q)
    {
    	int v1=p.fir,v2=q.fir;
    	return f[v1][1]+p.sec-f[v1][0]>f[v2][1]+q.sec-f[v2][0];
    }
    
    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;
    }
    
    void add(int u,int v,int w)
    {
    	all++;sq[all].to=v;sq[all].nxt=head[u];sq[all].cost=w;head[u]=all;
    }
    
    void dfs(int u,int fu)
    {
    	int cnt=0;
    	for (int i=head[u];i;i=sq[i].nxt)
    	{
    		int v=sq[i].to;
    		if (v==fu) continue;
    		dfs(v,u);
    		if (f[v][1]+sq[i].cost>f[v][0]) cnt++;
    	}
    	if (cnt<k)
    	{
    		for (int i=head[u];i;i=sq[i].nxt)
    		{
    			int v=sq[i].to;
    			if (v==fu) continue;
    			ll now=max(f[v][0],f[v][1]+sq[i].cost);
    			f[u][0]+=now;f[u][1]+=now;
    		}
    	}
    	else
    	{
    		tot=0;
    		for (int i=head[u];i;i=sq[i].nxt)
    		{
    			int v=sq[i].to;
    			if (v==fu) continue;
    			son[++tot]=mp(v,sq[i].cost);
    		}
    		sort(son+1,son+1+tot,cmp);
    		rep(i,1,k-1)
    		{
    			int v=son[i].fir,w=son[i].sec;
    			f[u][0]+=(f[v][1]+w);
    		}
    		f[u][1]=f[u][0];
    		int v=son[k].fir,w=son[k].sec;
    		f[u][0]+=f[v][1]+w;
    		f[u][1]+=max(f[v][0],f[v][1]);
    		rep(i,k+1,tot)
    		{
    			int v=son[i].fir;
    			f[u][0]+=max(f[v][0],f[v][1]);
    			f[u][1]+=max(f[v][0],f[v][1]);
    		}
    	}
    }
    
    int main()
    {
    	int T=read();
    	while (T--)
    	{
    		n=read();k=read();
    		rep(i,1,n-1)
    		{
    			int u=read(),v=read(),w=read();
    			add(u,v,w);add(v,u,w);
    		}
    		dfs(1,0);
    		printf("%lld
    ",max(f[1][0],f[1][1]));
    		all=0;
    		rep(i,1,n) f[i][0]=f[i][1]=head[i]=0;
    	}
    	return 0;
    }
    

    F

    感觉我做过这个题的原题

    暴力的话就是枚举区间([l,r])然后暴力做一个栈

    注意到([l,r])合法等价于([1,l-1])([1,r])这两个区间的栈中元素完全一致

    那么就只需要从头开始做一遍栈,沿途记录栈中元素的(hash)值,开个(map)记一下就可以了

    似乎并没有卡自然溢出?

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    typedef unsigned long long ull;
    const int N=10000;
    const db pi=acos(-1.0);
    #define lowbit(x) (x)&(-x)
    #define sqr(x) (x)*(x)
    #define rep(i,a,b) for (register int i=a;i<=b;i++)
    #define per(i,a,b) for (register int i=a;i>=b;i--)
    #define fir first
    #define sec second
    #define mp(a,b) make_pair(a,b)
    #define pb(a) push_back(a)
    #define maxd 998244353
    #define eps 1e-8
    #define bas 300007
    int n,a[300300],tp,sta[300300];
    map<ull,int> mp;
    ull hsh[300300];
    
    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;
    }
    
    int main()
    {
    	int T=read();
    	while (T--)
    	{
    		n=read();
    		rep(i,1,n) a[i]=read();
    		tp=0;ll ans=0;mp.clear();mp[0]=1;
    		rep(i,1,n)
    		{
    			if ((tp) && (sta[tp]==a[i])) tp--;
    			else {sta[++tp]=a[i];hsh[tp]=hsh[tp-1]*bas+a[i];}
    			ans+=mp[hsh[tp]];mp[hsh[tp]]++;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    QQ恢复解散后的群聊或删除后的好友的方法
    微软双屏手机Surface Duo曝新料
    利用Travis CI+GitHub实现持续集成和自动部署
    利用echarts展示旅行足迹
    03_K近邻算法
    02_感知机算法
    《面试官之你说我听》:简明的图解Redis RDB持久化、AOF持久化
    【绝对有收获】看看?必须告诉你为什么要使用MQ消息中间件(图解版)
    推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)
    利用window.performance.timing进行性能分析
  • 原文地址:https://www.cnblogs.com/encodetalker/p/11632920.html
Copyright © 2011-2022 走看看