标签:vector 它的 lin 没有 clu ++ utc ack putchar
有\(n\)个数,\(a_1,a_2,...,a_n\)。
该题中\(m\)个数的中位数的定义是:将这\(m\)个数排序后,排在第\(\lfloor \frac{m+1}{2}\rfloor\)的数。
可以进行的操作是:选一个区间\([l,r]\),将\(a_l,a_{l+1},...,a_r\)都变成\(a_l,a_{l+1},...,a_r\)的中位数。
给出\(a_1,...,a_n\)和\(k\),问能否把所有数都变成\(k\)。
\(n\leq 10^5;a_1,...,a_n,k\leq 10^9\)。
存在长度不少于2且区间内大于等于\(k\)的数的个数多于小于\(k\)的数的个数的区间。
首先,如果\(k\)在\(a_1,...,a_n\)中没出现过,就肯定不行;如果只有一个数而且和\(k\)相等,就肯定行。
一次“操作”可以把相邻两个数都变为它们之中较小的那个(称为“第一招”),也可以把有两个数相等的相邻的三个数变成那两个数的值(称为“第二招”)。
对于区间\([l,r](l<r)\),如果区间中位数大于等于\(k\):
(1)\(a_l,...,a_r\)中没有\(k\):\(k\)会出现在\(l\)左侧或\(r\)右侧,一次操作把\(a_l,...,a_r\)都变成大于\(k\)的数,用“第二招”可以使与\(k\)相邻的地方出现多个比\(k\)大的数,再用“第一招”可以把这些大于\(k\)的数都变成\(k\),再用“第二招”把所有数都变成\(k\);
(2)\(a_l,...,a_r\)中有\(k\):如果这些数的中位数就是\(k\),直接把它们变成\(k\),再用“第二招”把所有数变成\(k\);如果中位数大于\(k\),会发现\(k\)的某一侧的中位数也是大于等于\(k\),就和(1)相同。
所以“存在一个长度不少于2的区间中位数大于等于\(k\)”是“能把所有数变成\(k\)”的充分条件。
当不存在不少于2的区间中位数大于等于\(k\)时,任何一个区间的中位数都小于\(k\),所以任何操作都只会把一些数变成小于\(k\)的数,不能把所有数变成\(k\)。所以“存在一个长度不少于2的区间中位数大于等于\(k\)”是“能把所有数变成\(k\)”的必要条件。
所以判断“存在一个长度不少于2的区间中位数大于等于\(k\)”就行。
“区间中位数大于等于\(k\)”等价于“区间大于等于\(k\)的数多于小于\(k\)的数”,等价于“区间大于等于\(k\)的数的个数减小于\(k\)的数的个数大于0”。
把“大于等于\(k\)的数”看成1,“小于\(k\)的数”看成-1,判断前缀和的正负。
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#define LL long long
#define rep(i,x,y) for(int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define maxn 100007
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!=‘-‘)ch=getchar();
if(ch==‘-‘)f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar();
return x*f;
}
void write(int x)
{
char ch[20];int f=0;
if(!x){putchar(‘0‘),putchar(‘\n‘);return;}
if(x<0)putchar(‘-‘),x=-x;
while(x)ch[++f]=x%10+‘0‘,x/=10;
while(f)putchar(ch[f--]);
putchar(‘\n‘);
}
int t,n,k,a[maxn],b[maxn];
int main()
{
t=read();
while(t--)
{
n=read(),k=read();int jud1=0;
rep(i,1,n){a[i]=read();if(a[i]==k)jud1=1;}
if(!jud1){puts("no");continue;}
if(n==1){puts("yes");continue;}
rep(i,1,n){if(a[i]>=k)b[i]=1;else b[i]=-1;}
rep(i,1,n)b[i]+=b[i-1];
int mn=0;jud1=0;
rep(i,2,n)
{
mn=min(mn,b[i-2]);
if(b[i]-mn>0){jud1=1;break;}
}
puts(jud1?"yes":"no");
}
return (~(0-0)+1);
}
有一个\(n\times m\)的网格,每个格有一个0或1的数。
“好”的格的定义为:该格正上、正下、正左、正右与它相邻的格上的数都与它不同。
每操作一次,会把所有“好”的格上的数异或1,不是“好”的格上的数不变。
\(t\)组询问,每次给出\(x,y,k\),问\(k\)次操作后在\((x,y)\)格上的数。
\(n,m\leq 1000;t\leq 10^5\)。
对于一个“好”的格,它旁边的那个跟它数一样的格在操作后会跟它一起变,所以“好”的格一直都是“好”的。
对于一个不“好”的格,如果有一个与它相邻的格子是“好”的,那么这次操作它不会变,与它相邻的“好”格子会变,它们在这场操作后数相同,原来不“好”的格会变成“好”格。
所以,对于“好”格,\(k\)次操作后格上的数会异或上\(k\)个1;对于不“好”格,\(k\)小于它到离它最近的“好”格的距离它的数就不变,\(k\)大于等于它到离它最近的“好”格的距离它就异或上\(k-距离\)个1。
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#define LL long long
#define rep(i,x,y) for(int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define maxn 1007
using namespace std;
LL read()
{
LL x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!=‘-‘)ch=getchar();
if(ch==‘-‘)f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar();
return x*f;
}
void write(int x)
{
char ch[20];int f=0;
if(!x){putchar(‘0‘),putchar(‘\n‘);return;}
if(x<0)putchar(‘-‘),x=-x;
while(x)ch[++f]=x%10+‘0‘,x/=10;
while(f)putchar(ch[f--]);
putchar(‘\n‘);
}
int n,m,t,dis[maxn][maxn],qx[maxn*maxn],qy[maxn*maxn],hd,tl;
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
char s[maxn][maxn];
inline int in(int x,int y){if(1<=x&&x<=n&&1<=y&&y<=m)return 1;return 0;}
int main()
{
n=read(),m=read(),t=read();hd=1;
rep(i,1,n){scanf("%s",s[i]+1);}
rep(i,1,n)rep(j,1,m)
{
int yes=0;
rep(k,0,3)
{
int nx=i+dx[k],ny=j+dy[k];
if(in(nx,ny)&&s[nx][ny]==s[i][j]){yes=1;break;}
}
if(yes)++tl,qx[tl]=i,qy[tl]=j;
else dis[i][j]=-1;
}
while(hd<=tl)
{
int ux=qx[hd],uy=qy[hd];hd++;
rep(k,0,3)
{
int nx=ux+dx[k],ny=uy+dy[k];
if(in(nx,ny)&&dis[nx][ny]==-1){dis[nx][ny]=dis[ux][uy]+1,tl++,qx[tl]=nx,qy[tl]=ny;}
}
}
if(tl){rep(i,1,n)rep(j,1,m)if(dis[i][j]==-1)return 0;}
while(t--)
{
int x=read(),y=read();LL k=read();
if(!tl||k<(LL)dis[x][y])putchar(s[x][y]),putchar(‘\n‘);
else write((s[x][y]-‘0‘)^((k-(LL)dis[x][y])&1ll));
}
return (~(0-0)+1);
}
小号也能打div1啦!
想做个拿猎虫打龙蚀虫的视频。
并不对劲的CF1349B&C:Game of Median Life
标签:vector 它的 lin 没有 clu ++ utc ack putchar
原文地址:https://www.cnblogs.com/xzyf/p/12884827.html