Codeforces Round #773 (Div. 2)

A

只有这种情况答案不为 \(0\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline 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;
}
void write(int n)
{
	if(n<0){putchar('-');n=-n;}
	if(n>9)write(n/10);
	putchar(n%10^48);
}
int x[3],y[3];
void sol()
{
	for(int i=0;i<3;i++)x[i]=read(),y[i]=read();
	for(int i=0;i<3;i++)
	{
		for(int j=i+1;j<3;j++)
		{
			if(y[i]==y[j])
			{
				if(y[3-i-j]>y[i])return puts("0"),void();
				else return printf("%d\n",abs(x[i]-x[j])),void();
			}
		}
	}
	puts("0");
}
int main()
{
	int T=read();
	while(T--)sol();
}
//zzt qwq

B

见代码。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline 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;
}
void write(int n)
{
	if(n<0){putchar('-');n=-n;}
	if(n>9)write(n/10);
	putchar(n%10^48);
}
const int N=3e5+10;
map<int,bool> vis;
int a[N];
void sol()
{
	vis.clear();
	int n=read(),c=0;
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		if(!vis[a[i]])c++;
		vis[a[i]]=1;
	}
	for(int i=1;i<=c;i++)printf("%d ",c);
	for(int i=c+1;i<=n;i++)printf("%d ",i);
	puts("");
}
int main()
{
	int n=read();
	while(n--)sol();
}
//zzt qwq

C

直接大力贪。

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline 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;
}
void write(int n)
{
	if(n<0){putchar('-');n=-n;}
	if(n>9)write(n/10);
	putchar(n%10^48);
}
const int N=2e5+10;
int a[N];
map<int,int> cnt;
void sol()
{
	cnt.clear();
	int n=read(),x=read();
	for(int i=1;i<=n;i++)a[i]=read(),cnt[a[i]]++;
	sort(a+1,a+n+1);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(!cnt[a[i]])continue;
		if(cnt[a[i]*x])cnt[a[i]]--,cnt[a[i]*x]--;
		else cnt[a[i]]--,ans++;
	}
	printf("%lld\n",ans);
}
signed main()
{
	int T=read();
	while(T--)sol();
}
//zzt qwq

D

首先如果有数值出现计数词显然不合法。

否则的话维护一个 vector,对于当前的第一位,找到后面第一个匹配到他的位置 \(k\),然后在 \(k\) 后面暴力加使得 \([1,k)\)\([k,2k)\) 这段区间的数是对应相等的,然后消掉这段区间,再继续做。

可以证明复杂度是正确的,但我不会证。感性理解一下大概就是 \(\mathcal O(n^3)\) 左右的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline 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;
}
void write(int n)
{
	if(n<0){putchar('-');n=-n;}
	if(n>9)write(n/10);
	putchar(n%10^48);
}
const int N=1e6+10;
int vis[N];
int a[N];
map<int,int> cnt;
void sol(int T)
{
	cnt.clear();
	vector<int> v;
	int n=read();
	for(int i=1;i<=n;i++)a[i]=read(),cnt[a[i]]++,v.pb(a[i]);
	for(auto it:cnt)if(it.se&1)return puts("-1"),void();
	vector<pii> Ans;
	vector<int> len;
//	puts("TEST1");
	for(int i=0;i<v.size();i++)
	{
//		printf("i=%d\n",i);
		if(vis[i]==T)continue;
		int k=0;
		for(int j=i+1;j<v.size();j++)
		{
			if(v[j]==v[i])
			{
				k=j;
				break;
			}
		}
//		printf("k=%d\n",k);
		for(int j=i;j<k;j++)
		{
//			printf("j=%d\n",j);
			if(k+(j-i)<v.size()&&v[k+(j-i)]==v[j])vis[k+(j-i)]=T;
			else
			{
				Ans.pb(mp(k+(j-i),v[j]));
				if(k+(j-i)==v.size())
				{
//					puts("!!");
					v.pb(v[j]);
					v.pb(v[j]);
//					printf("v.size()=%d\n",(int)v.size());
				}
				else
				{
//					printf("v.size=%d\n",(int)v.size());
//					puts("??");
//					printf("k+(j-i)=%d\n",k+(j-i));
					v.insert(v.begin()+(k+(j-i)),v[j]);
					v.insert(v.begin()+(k+(j-i)),v[j]);
				}
				vis[k+(j-i)]=T;
			}
			vis[j]=T;
		}
		len.pb((k-i)*2);
	}
	printf("%d\n",(int)Ans.size());
	for(auto it:Ans)printf("%d %d\n",it.fi,it.se);
	printf("%d\n",(int)len.size());
	for(auto it:len)printf("%d ",it);
	puts("");
}
int main()
{
	int T=read();
	for(int i=1;i<=T;i++)sol(i);
}
//zzt qwq

E

可以发现一个人 \(p\) 能被确认是有病当且仅当存在一个 \(0\;l\;r\;1\) 操作使得 \(p\in[l,r]\) 且区间内其他人都被确认没病,能被确认没病就是被一个 \(1\;l\;r\;0\) 覆盖过。

考虑把操作离线下来,将所有的 \(1\;l\;r\;0\) 操作先做一遍,然后再对所有的 \(1\;l\;r\;1\) 看是否区间有且仅有一个数没被钦定为 \(0\),记录下这个数被确认为 \(1\) 的最小时间,查询操作即考虑最小时间和当前操作时间的大小关系。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline 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;
}
void write(int n)
{
	if(n<0){putchar('-');n=-n;}
	if(n>9)write(n/10);
	putchar(n%10^48);
}
const int N=2e5+10;
struct sgt{
	struct seg{
		int l,r,min,tag;
		seg(){l=r=0,min=tag=1e9;}
	}t[N<<2];
	void build(int p,int l,int r)
	{
		t[p].l=l,t[p].r=r;
		t[p].min=t[p].tag=1e9;
		if(l==r)return;
		int mid=(l+r)>>1;
		build(p*2,l,mid);
		build(p*2+1,mid+1,r);
	}
	void pd(int p)
	{
		if(t[p].tag!=1e9)
		{
			t[p*2].tag=min(t[p*2].tag,t[p].tag);
			t[p*2+1].tag=min(t[p*2+1].tag,t[p].tag);
			t[p*2].min=min(t[p*2].min,t[p].tag);
			t[p*2+1].min=min(t[p*2+1].min,t[p].tag);
			t[p].tag=1e9;
		}
	}
	void modify(int p,int l,int r,int d)
	{
		if(l<=t[p].l&&t[p].r<=r)
		{
			t[p].min=min(t[p].min,d);
			t[p].tag=min(t[p].tag,d);
			return;
		}
		pd(p);int mid=(t[p].l+t[p].r)>>1;
		if(l<=mid)modify(p*2,l,r,d);
		if(r>mid)modify(p*2+1,l,r,d);
		t[p].min=min(t[p*2].min,t[p*2+1].min);
	}
	int query(int p,int l,int r)
	{
//		printf("query[%d, %d], now[%d, %d]\n",l,r,t[p].l,t[p].r);
		if(l<=t[p].l&&t[p].r<=r)return t[p].min;
		pd(p);int mid=(t[p].l+t[p].r)>>1,ans=1e9;
		if(l<=mid)ans=min(ans,query(p*2,l,r));
		if(r>mid)ans=min(ans,query(p*2+1,l,r));
		return ans;
	}
}T;
struct Query{
	int t;
	int l,r,x;
}q[N];
int f[N],sum[N];
int st[N][30],Log[N];
int query(int l,int r)
{
	int x=Log[r-l+1];
	return max(st[l][x],st[r-(1<<x)+1][x]);
}
int g[N];
int main()
{
	int n=read(),m=read();
	T.build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		q[i].t=read();
		if(q[i].t==0)q[i].l=read(),q[i].r=read(),q[i].x=read();
		else q[i].x=read();
	}
	for(int i=1;i<=m;i++)if(q[i].t==0&&q[i].x==0)T.modify(1,q[i].l,q[i].r,i);
	for(int i=1;i<=n;i++)f[i]=T.query(1,i,i);
	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+(f[i]!=1e9);
	for(int i=2;i<=n;i++)Log[i]=Log[i>>1]+1;
	for(int i=1;i<=n;i++)if(f[i]!=1e9)st[i][0]=f[i];
	for(int j=1;j<=Log[n];j++)for(int i=1;i+(1<<j)-1<=n;i++)st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
//	for(int i=1;i<=n;i++)printf("%d ",f[i]);puts("!!??!!!?");
//	for(int i=1;i<=n;i++)printf("%d ",sum[i]-sum[i-1]);
//	puts("!!");
	memset(g,0x7f,sizeof(g));
	for(int i=1;i<=m;i++)
	{
		if(q[i].t==0&&q[i].x==1)
		{
			int l=q[i].l,r=q[i].r;
			if(sum[r]-sum[l-1]==r-l){
//				puts("FUCK!");
				int tm=max(query(l,r),i);
				int L=l,R=r,pos=0;
				while(L<=R)
				{
					int mid=(L+R)>>1;
					if(sum[mid]-sum[l-1]<mid-l+1)R=mid-1,pos=mid;
					else L=mid+1;
				}
//				printf("pos=%d??????, tm=%d\n",pos,tm);
				g[pos]=min(g[pos],tm);
			}
		}
	}
	T.build(1,1,n);
	for(int i=1;i<=m;i++)
	{
//		printf("%d, %d, %d, %d\n",q[i].t,q[i].l,q[i].r,q[i].x);
		if(q[i].t==0&&q[i].x==0)T.modify(1,q[i].l,q[i].r,0);
		else if(q[i].t==1)
		{
			if(g[q[i].x]<=i)
				puts("YES");
			else if(T.query(1,q[i].x,q[i].x)==0)
				puts("NO");
			else 
				puts("N/A");
		}
//		for(int j=1;j<=n;j++)printf("%d ",T.query(1,j,j));
//		puts("!!!");
	}
}
//zzt qwq

F

还不会。

posted @ 2022-02-26 08:52  zzt1208  阅读(67)  评论(1编辑  收藏  举报