zoukankan      html  css  js  c++  java
  • Codeforces Round #567 Div. 2

      A:签到。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    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;
    }
    ll x,y,z;
    signed main()
    {
    	cin>>x>>y>>z;
    	cout<<(x+y)/z<<' ';
    	if (x%z+y%z<z) cout<<0;
    	else cout<<min(z-x%z,z-y%z);
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      B:显然在中间截比较优。于是就找到在左侧和在右侧的最靠近中点的切割点。注意不能有前导0。高精加即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 100010
    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],b[N],c[N],d[N],len1=N,len2=N;
    char s[N];
    signed main()
    {
    	n=read();
    	scanf("%s",s+1);
    	int x=0,y=n+1;
    	for (int i=1;i<n;i++)
    	if (s[i+1]!='0')
    	{
    		if (i<=n/2) x=max(x,i);
    		else y=min(y,i);
    	}
    	if (x>0)
    	{
    		int lena=0,lenb=0;
    		for (int i=x;i>=1;i--) a[++lena]=s[i]-'0';
    		for (int i=n;i>x;i--) b[++lenb]=s[i]-'0';
    		for (int i=1;i<=max(lena,lenb);i++)
    		{
    			a[i]+=b[i];
    			a[i+1]+=a[i]/10;
    			a[i]%=10;
    		}
    		len1=max(lena,lenb);
    		if (a[len1+1]) len1++;
    	}
    	if (y<=n)
    	{
    		int lena=0,lenb=0;
    		for (int i=y;i>=1;i--) c[++lena]=s[i]-'0';
    		for (int i=n;i>y;i--) d[++lenb]=s[i]-'0';
    		for (int i=1;i<=max(lena,lenb);i++)
    		{
    			c[i]+=d[i];
    			c[i+1]+=c[i]/10;
    			c[i]%=10;
    		}
    		len2=max(lena,lenb);
    		if (c[len2+1]) len2++;
    	}
    	if (len1<len2)
    	{
    		for (int i=len1;i>=1;i--) printf("%d",a[i]);
    	}
    	else
    	if (len1>len2)
    	{
    		for (int i=len2;i>=1;i--) printf("%d",c[i]);
    	}
    	else
    	{
    		bool flag1=0;
    		for (int i=len1;i>=1;i--)
    		if (a[i]!=c[i])
    		{
    			flag1=a[i]<c[i];
    			break;
    		}
    		if (flag1) for (int i=len1;i>=1;i--) printf("%d",a[i]);
    		else for (int i=len2;i>=1;i--) printf("%d",c[i]);
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      C:每个点处理出该列中以该位置为起点形成的三段是什么样子的。注意第三段长度对第二段取min。然后枚举每一行,找到三段相同且合法的子段计算贡献即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 1010
    #define mp(x,y) make_pair((x),(y))
    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<char,int> pii;
    int n,m;
    pii f[N][N][3];
    char a[N][N];
    ll ans;
    bool issame(int i,int x,int y)
    {
    	for (int j=0;j<3;j++)
    	if (f[i][x][j]!=f[i][y][j]) return 0;
    	return 1;
    }
    signed main()
    {
    	n=read(),m=read();
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    		a[i][j]=getc();
    	for (int i=1;i<=m;i++) f[n][i][0]=mp(a[n][i],1);
    	for (int i=n-1;i>=1;i--)
    		for (int j=1;j<=m;j++)
    		if (a[i][j]==a[i+1][j])
    		{
    			for (int k=0;k<3;k++) f[i][j][k]=f[i+1][j][k];
    			f[i][j][0].second++;
    		}
    		else
    		{
    			for (int k=1;k<3;k++) f[i][j][k]=f[i+1][j][k-1];
    			f[i][j][0]=mp(a[i][j],1);
    		}
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    		f[i][j][2].second=min(f[i][j][2].second,f[i][j][1].second);
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=1;j<=m;j++)
    		{
    			int t=j;
    			while (t<m&&issame(i,j,t+1)) t++;
    			if (f[i][j][0].second==f[i][j][1].second&&f[i][j][1].second==f[i][j][2].second) ans+=(t-j+1)*(t-j+2)/2;
    			j=t;
    		}
    	}
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:可以首先对每个询问二分出该次要加的数的值是多少。然后问题变为多次询问序列中第k个<=p的数是多少。可以将数从小到大考虑,treap维护查询第k大。事实上直接离线即可,开始的二分有点多余。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 500010 
    #define int long long
    #define lson tree[k].ch[0]
    #define rson tree[k].ch[1]
    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,q,a[N],b[N],s[N],cnt[N],root,Cnt;
    struct data
    {
    	int k,p,i,ans;
    	bool operator <(const data&a) const
    	{
    		return i<a.i;
    	}
    }Q[N];
    bool cmp(const data&a,const data&b)
    {
    	return a.p<b.p;
    }
    vector<int> pos[N];
    struct data2{int ch[2],s,p,x;
    }tree[N];
    void up(int k){tree[k].s=tree[lson].s+tree[rson].s+1;}
    void move(int &k,int p)
    {
        int t=tree[k].ch[p];
        tree[k].ch[p]=tree[t].ch[!p],tree[t].ch[!p]=k,up(k),up(t),k=t;
    }
    void ins(int &k,int x)
    {
        if (k==0) {k=++Cnt;tree[k].x=x,tree[k].p=rand(),tree[k].s=1;return;}
        tree[k].s++;
        if (tree[k].x<x) {ins(rson,x);if (tree[rson].p>tree[k].p) move(k,1);}
        else {ins(lson,x);if (tree[lson].p>tree[k].p) move(k,0);}
    }
    int query(int k,int x)
    {
        if (tree[lson].s+1==x) return tree[k].x;
        if (tree[lson].s+1>x) return query(lson,x);
        else return query(rson,x-tree[lson].s-1);
    }
    signed main()
    {
    	srand(time(0));
    	m=read(),n=read(),q=read();
    	for (int i=1;i<=m;i++) a[read()]++;
    	for (int i=1;i<=n;i++) pos[a[i]].push_back(i);
    	for (int i=1;i<=n;i++) b[a[i]]++;cnt[0]=b[0];
    	for (int i=1;i<=m;i++) s[i]=s[i-1]+i*b[i],cnt[i]=cnt[i-1]+b[i];
    	for (int i=1;i<=q;i++) 
    	{
    		Q[i].i=i;
    		int x=read()-m;
    		if (x+m>m*n) Q[i].k=(x+m-1)%n+1,Q[i].p=m; 
    		else
    		{
    			int l=0,r=m,p=0;
    			while (l<=r) 
    			{
    				int mid=l+r>>1;
    				if (cnt[mid]*mid-s[mid]<x) p=mid,l=mid+1;
    				else r=mid-1;
    			}
    			int k=x-(cnt[p]*p-s[p]);
    			Q[i].k=k,Q[i].p=p;
    		}
    	}
    	sort(Q+1,Q+q+1,cmp);
    	int cur=0;
    	for (int i=0;i<=m;i++)
    	{
    		for (int j:pos[i]) ins(root,j);
    		while (cur<q&&Q[cur+1].p==i)
    		{
    			cur++;
    			Q[cur].ans=query(root,Q[cur].k);
    		}
    	}
    	sort(Q+1,Q+q+1);
    	for (int i=1;i<=q;i++) printf("%d
    ",Q[i].ans);
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      E:E1就是个思博暴力,显然能切就切不会改变可行性。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 100010
    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,b[N<<2],t;
    int cnt[N<<2];
    struct data{int x1,y1,x2,y2;
    }a[N],c[N];
    bool solve(int l,int r)
    {
    	if (l==r) return 1;
    	for (int i=1;i<=t;i++) cnt[i]=0;
    	for (int i=l;i<=r;i++) cnt[a[i].x1+1]++,cnt[a[i].x2]--;
    	int mx=0,mn=t+1;
    	for (int i=l;i<=r;i++) mx=max(mx,a[i].x1),mn=min(mn,a[i].x2);
    	int s=0,p=-1;
    	for (int i=1;i<=t;i++)
    	{
    		s+=cnt[i];
    		if (i>=mn&&i<=mx&&s==0) {p=i;break;}
    	}
    	if (p!=-1)
    	{
    		int u=l-1;
    		for (int i=l;i<=r;i++) 
    		if (a[i].x2<=p) c[++u]=a[i];
    		int mid=u;
    		for (int i=l;i<=r;i++)
    		if (a[i].x1>=p) c[++u]=a[i];
    		for (int i=l;i<=r;i++) a[i]=c[i];
    		return solve(l,mid)&&solve(mid+1,r);
    	}
    	for (int i=1;i<=t;i++) cnt[i]=0;
    	for (int i=l;i<=r;i++) cnt[a[i].y1+1]++,cnt[a[i].y2]--;
    	mx=0,mn=t+1;
    	for (int i=l;i<=r;i++) mx=max(mx,a[i].y1),mn=min(mn,a[i].y2);
    	s=0,p=-1;
    	for (int i=1;i<=t;i++)
    	{
    		s+=cnt[i];
    		if (i>=mn&&i<=mx&&s==0) {p=i;break;}
    	}
    	if (p!=-1)
    	{
    		int u=l-1;
    		for (int i=l;i<=r;i++) 
    		if (a[i].y2<=p) c[++u]=a[i];
    		int mid=u;
    		for (int i=l;i<=r;i++)
    		if (a[i].y1>=p) c[++u]=a[i];
    		for (int i=l;i<=r;i++) a[i]=c[i];
    		return solve(l,mid)&&solve(mid+1,r);
    	}
    	return 0;
    }
    signed main()
    {
    	n=read();
    	for (int i=1;i<=n;i++)
    	{
    		b[++t]=a[i].x1=read();
    		b[++t]=a[i].y1=read();
    		b[++t]=a[i].x2=read();
    		b[++t]=a[i].y2=read();
    	}
    	sort(b+1,b+t+1);
    	t=unique(b+1,b+t+1)-b-1;
    	for (int i=1;i<=n;i++)
    	{
    		a[i].x1=lower_bound(b+1,b+t+1,a[i].x1)-b;
    		a[i].y1=lower_bound(b+1,b+t+1,a[i].y1)-b;
    		a[i].x2=lower_bound(b+1,b+t+1,a[i].x2)-b;
    		a[i].y2=lower_bound(b+1,b+t+1,a[i].y2)-b;
    	}
    	if (solve(1,n)) cout<<"YES";else cout<<"NO";
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      E2的话,基本思路肯定没法有什么变化,如果要保证复杂度,容易想到每次切割都只能花费相当于较少部分矩形个数的代价。那么首先切割时不能把两部分分别递归下去,而是要递归较少的部分并把其从整体中删掉,可以链表实现。然后考虑怎样以这样的复杂度找到一种切割方案。将矩形集合复制成四份,并分别按x1,x2,y1,y2排序,同时处理四份矩形集合,找到一种切割时就立即停止,这样就能保证扫过的部分矩形数量不大于一半了。判断能否切割只需要记录另一维坐标的极值,比如对于x1从小到大排序后,记录x2的最大值即可。实现时像我一样蠢的话就会出现大量的同一份代码写四次。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 100010
    #define del(x) {nxt1[pre1[pos1[x]]]=nxt1[pos1[x]];pre1[nxt1[pos1[x]]]=pre1[pos1[x]];nxt2[pre2[pos2[x]]]=nxt2[pos2[x]];pre2[nxt2[pos2[x]]]=pre2[pos2[x]];nxt3[pre3[pos3[x]]]=nxt3[pos3[x]];pre3[nxt3[pos3[x]]]=pre3[pos3[x]];nxt4[pre4[pos4[x]]]=nxt4[pos4[x]];pre4[nxt4[pos4[x]]]=pre4[pos4[x]];}
    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;
    struct data{int x1,y1,x2,y2,i;
    }a[N];
    bool cmp1(const data&a,const data&b)
    {
    	return a.x1<b.x1;
    }
    bool cmp2(const data&a,const data&b)
    {
    	return a.x2>b.x2;
    }
    bool cmp3(const data&a,const data&b)
    {
    	return a.y1<b.y1;
    }
    bool cmp4(const data&a,const data&b)
    {
    	return a.y2>b.y2;
    }
    bool solve(data *a,int n)
    {
    	data a1[n+1],a2[n+1],a3[n+1],a4[n+1];
    	int nxt1[n+2],nxt2[n+2],nxt3[n+2],nxt4[n+2];
    	int pre1[n+2],pre2[n+2],pre3[n+2],pre4[n+2];
    	for (int i=0;i<=n;i++)
    	{
    		a[i].i=i;
    		a1[i]=a2[i]=a3[i]=a4[i]=a[i];
    		nxt1[i]=nxt2[i]=nxt3[i]=nxt4[i]=i+1;
    		pre1[i+1]=pre2[i+1]=pre3[i+1]=pre4[i+1]=i;
    	}
    	sort(a1+1,a1+n+1,cmp1);sort(a2+1,a2+n+1,cmp2);sort(a3+1,a3+n+1,cmp3);sort(a4+1,a4+n+1,cmp4);
    	int pos1[n+2],pos2[n+2],pos3[n+2],pos4[n+2];
    	for (int i=1;i<=n;i++) pos1[a1[i].i]=i,pos2[a2[i].i]=i,pos3[a3[i].i]=i,pos4[a4[i].i]=i;
    	while (n>1)
    	{
    		int tmp=0;
    		int mxx2=-inf,mnx1=inf,mxy2=-inf,mny1=inf;
    		int cur1=0,cur2=0,cur3=0,cur4=0;
    		bool flag=0;
    		for (int i=1;i<=n/2;i++)
    		{
    			cur1=nxt1[cur1];
    			cur2=nxt2[cur2];
    			cur3=nxt3[cur3];
    			cur4=nxt4[cur4];
    			mxx2=max(mxx2,a1[cur1].x2);
    			mnx1=min(mnx1,a2[cur2].x1);
    			mxy2=max(mxy2,a3[cur3].y2);
    			mny1=min(mny1,a4[cur4].y1);
    			if (mxx2<=a1[nxt1[cur1]].x1)
    			{
    				flag=1;
    				data b[i+1];
    				for (int j=1;j<=i;j++)
    				{
    					b[j]=a1[cur1];
    					int x=a1[cur1].i;
    					cur1=pre1[cur1];
    					del(x);
    				}
    				if (!solve(b,i)) return 0;
    				else {n-=i;break;}
    			}
    			if (mnx1>=a2[nxt2[cur2]].x2)
    			{
    				flag=1;
    				data b[i+1];
    				for (int j=1;j<=i;j++)
    				{
    					b[j]=a2[cur2];
    					int x=a2[cur2].i;
    					cur2=pre2[cur2];
    					del(x);
    				}
    				if (!solve(b,i)) return 0;
    				else {n-=i;break;}
    			}
    			if (mxy2<=a3[nxt3[cur3]].y1)
    			{
    				flag=1;
    				data b[i+1];
    				for (int j=1;j<=i;j++)
    				{
    					b[j]=a3[cur3];
    					int x=a3[cur3].i;
    					cur3=pre3[cur3];
    					del(x);
    				}
    				if (!solve(b,i)) return 0;
    				else {n-=i;break;}
    			}
    			if (mny1>=a4[nxt4[cur4]].y2)
    			{
    				flag=1;
    				data b[i+1];
    				for (int j=1;j<=i;j++)
    				{
    					b[j]=a4[cur4];
    					int x=a4[cur4].i;
    					cur4=pre4[cur4];
    					del(x);
    				}
    				if (!solve(b,i)) return 0;
    				else {n-=i;break;}
    			}
    		}
    		if (!flag) return 0;
    	}
    	return 1;
    }
    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].x1=read(),a[i].y1=read(),a[i].x2=read(),a[i].y2=read();
    	if (solve(a,n)) cout<<"YES";else cout<<"NO";
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      小小小小号。result:rank 3 rating +218

  • 相关阅读:
    Hadoop 3.1.1
    java乐观锁和悲观锁
    git push时提示The authenticity of host 'github.com (52.74.223.119)' can't be established.
    github 提交使用git commit,报错Please tell me who you are
    Mac adb 提示 command not found. 解决办法
    Mac系统下安卓使用uiautomator配置SDK及真机环境配置
    python随笔:启动django报错
    ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/Library/Python/2.7/site-packages/Django-1.11.23.dist-info' Consider using the `--user` option or check the
    Python中安装bs4后,pycharm依然报错ModuleNotFoundError: No module named 'bs4'
    Python中__init__和self的意义和作用
  • 原文地址:https://www.cnblogs.com/Gloid/p/11061529.html
Copyright © 2011-2022 走看看