zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 62 Div. 2

      突然发现上一场edu忘记写了(

      A:签到。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 10010 
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,a[N],ans;
    bool flag[N];
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=n;i++)
    	{
    		int x=a[i];
    		ans++;
    		while (i<x)
    		{
    			i++;
    			x=max(x,a[i]);
    		}
    	}
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      B:显然仅当最左为>或最右为<时才能消去整个字符串。于是找到最左的>和最右的<取min即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 110 
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int T,n;
    char s[N];
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	T=read();
    	while (T--)
    	{
    		n=read();
    		scanf("%s",s+1);
    		int ans=n-1;
    		int last=0;
    		for (int i=n;i>=1;i--) if (s[i]=='<') {last=i;break;}
    		ans=min(ans,n-last);
    		int first=n;
    		for (int i=1;i<=n;i++) if (s[i]=='>') {first=i;break;}
    		ans=min(ans,first-1);
    		cout<<ans<<endl;
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      C:枚举beauty最小值,则显然应该选择beauty不小于该数的前k大。堆维护。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    #define ll long long
    #define N 300010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m;
    struct data
    {
    	int x,y; 
    	bool operator <(const data&a) const
    	{
    		return y<a.y;
    	}
    }a[N];
    priority_queue<int,vector<int>,greater<int> > q;
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("c.in","r",stdin);
    	freopen("c.out","w",stdout);
    #endif
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    	sort(a+1,a+n+1);
    	ll tot=0,ans=0;
    	for (int i=n;i>=1;i--)
    	{
    		q.push(a[i].x);tot+=a[i].x;
    		if (n-i+1>m) tot-=q.top(),q.pop();
    		ans=max(ans,tot*a[i].y);
    	}
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:大胆猜想不用证明。即让1与所有相邻点配对。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    #define ll long long
    #define N 510
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,f[N][N];
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("c.in","r",stdin);
    	freopen("c.out","w",stdout);
    #endif
    	n=read();
    	int ans=0;
    	for (int i=2;i<n;i++) ans+=i*(i+1);
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      E:不存在奇回文串的充要条件是不存在长度为3的回文串。黑白染色(也就是奇偶分开考虑),则相当于相邻数不同。已确定的数将序列分割成若干区间,显然这些区间之间无关。然后随便dp一发。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define int long long
    #define N 200010
    #define P 998244353
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,a[N],b[N],c[N],f[N],g[N],ans;
    int ksm(int a,int k)
    {
    	int s=1;
    	for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
    	return s;
    }
    int calc(int *a,int n)
    {
    	int ans=1;
    	bool flag=0;
    	for (int i=1;i<=n;i++) if (a[i]!=-1) {flag=1;break;}
    	if (!flag)
    	{
    		ans=m;for (int i=2;i<=n;i++) ans=1ll*ans*(m-1)%P;return ans;
    	}
    	int l=1,r=n;
    	if (a[1]==-1)
    	{
    		while (a[l+1]==-1) l++;
    		for (int i=1;i<=l;i++) ans=1ll*ans*(m-1)%P;
    		l++;
    	}
    	if (a[n]==-1)
    	{
    		while (a[r-1]==-1) r--;
    		for (int i=n;i>=r;i--) ans=1ll*ans*(m-1)%P;
    		r--;
    	}
    	for (int i=l;i<=r;i++)
    	{
    		if (i==r) break;
    		int t=i+1;
    		while (a[t]==-1) t++;
    		if (a[i]==a[t]) ans=1ll*ans*f[t-i]%P;
    		else ans=1ll*ans*g[t-i]%P;
    		i=t-1;
    	}
    	return ans;
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("c.in","r",stdin);
    	freopen("c.out","w",stdout);
    #endif
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	f[0]=1;for (int i=1;i<=n;i++) f[i]=(ksm(m-1,i-1)+P-f[i-1])%P;
    	g[0]=0;for (int i=1;i<=n;i++) g[i]=(ksm(m-1,i-1)+P-g[i-1])%P;
    	int u=0,v=0;
    	for (int i=1;i<=n;i++)
    	if (i&1) b[++u]=a[i];
    	else c[++v]=a[i];
    	ans=1ll*calc(b,u)*calc(c,v)%P;
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      F:https://www.cnblogs.com/Gloid/p/9392532.html 用上这一场的D的结论(woc怎么看着这么羞耻),然后相当于动态图连通性问题,码了个线段树分治+带撤销并查集,得卡卡常。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<vector>
    using namespace std;
    #define ll long long
    #define int long long
    #define N 300010
    #define mp(x,y) make_pair((x),(y))
    #define left(x) (x)
    #define right(x) ((x)+n)
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    typedef pair<int,int> pii;
    int n,t,fa[N<<1],lsize[N<<1],rsize[N<<1],L[N<<2],R[N<<2],lazy[N<<2];
    ll ans,Q[N];
    map<int,int> id[N];
    vector<pii> edge[N<<2];
    struct data{int x,y,z,l,r;
    }a[N];
    vector<data> stk[N<<2];
    void build(int k,int l,int r)
    {
    	L[k]=l,R[k]=r;
    	if (l==r) return;
    	int mid=l+r>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    }
    void add(int k,int l,int r,int x,int y)
    {
    	if (L[k]==l&&R[k]==r) {edge[k].push_back(mp(x,y));return;}
    	int mid=L[k]+R[k]>>1;
    	if (r<=mid) add(k<<1,l,r,x,y);
    	else if (l>mid) add(k<<1|1,l,r,x,y);
    	else add(k<<1,l,mid,x,y),add(k<<1|1,mid+1,r,x,y);
    }
    int find(int x){return fa[x]==x?x:find(fa[x]);}
    ll calc(int x){return 1ll*lsize[x]*rsize[x];}
    void solve(int k)
    {
    	lazy[k]=ans;
    	for (int i=0;i<edge[k].size();i++)
    	{
    		int x=edge[k][i].first,y=edge[k][i].second;
    		int p=find(left(x)),q=find(right(y));
    		if (p!=q)
    		{
    		ans-=calc(p);ans-=calc(q);
    		if (lsize[p]+rsize[p]<rsize[p]+rsize[q]) swap(p,q);
    		stk[k].push_back((data){q,p,fa[q],lsize[p],rsize[p]});
    		fa[q]=p;lsize[p]+=lsize[q];rsize[p]+=rsize[q];
    		ans+=calc(p);
    		}
    	}
    	if (L[k]==R[k]) Q[L[k]]=ans;
    	if (L[k]<R[k]) solve(k<<1),solve(k<<1|1);
    	ans=lazy[k];
    	for (int i=((int)stk[k].size())-1;i>=0;i--)
    	{
    		fa[stk[k][i].x]=stk[k][i].z;
    		lsize[stk[k][i].y]=stk[k][i].l;
    		rsize[stk[k][i].y]=stk[k][i].r;
    	}
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("f.in","r",stdin);
    	freopen("f.out","w",stdout);
    #endif
    	n=read();
    	for (int i=1;i<=n;i++) fa[left(i)]=left(i),fa[right(i)]=right(i),lsize[left(i)]=1,rsize[right(i)]=1;
    	for (int i=1;i<=n;i++)
    	{
    		int x=read(),y=read();
    		if (id[x][y]==0)
    		{
    			id[x][y]=++t;
    			a[t].x=x,a[t].y=y,a[t].l=i;
    		}
    		else
    		{
    			a[id[x][y]].r=i-1;
    			id[x][y]=0;
    		}
    	}
    	for (int i=1;i<=t;i++) if (a[i].r==0) a[i].r=n;
    	build(1,1,n);
    	for (int i=1;i<=t;i++) add(1,a[i].l,a[i].r,a[i].x,a[i].y);
    	solve(1);
    	for (int i=1;i<=n;i++) printf("%I64d ",Q[i]);
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      G:没补。

      小小号的第一场。因为E一直wa非常自闭。result:rank 98 rating +214

  • 相关阅读:
    组合模式
    迭代器模式
    命令模式
    装饰者模式
    观察者模式
    策略模式
    适配器模式和外观模式
    Servlet
    Java 递归
    Java 反射
  • 原文地址:https://www.cnblogs.com/Gloid/p/10757944.html
Copyright © 2011-2022 走看看