T1 洛希极限

不难发现每个点肯定是被它上一行或上一列的点转移。可以预处理出每个点上一行,上一列最远的能转移到它的点,然后单调队列优化。

预处理稍显ex。可以用并查集维护一个链表,记录当前点之后第一个没有被预处理的点的位置,这样就保证了每个点只会被更新一次。

同时正因为只被更新一次,所以行列的预处理都应先排序。

单调队列可以手写结构体,维护方案数比较方便。

\(code:\)

T1

#include<bits/stdc++.h>
using namespace std;
#define int long long namespace IO{
typedef long long LL;
auto read=[]()->int{
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
};
auto write=[](LL x,int sp)->void{
char ch[20]; int len=0;
if(x<0){ x=~x+1; putchar('-'); }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
};
auto ckmax=[](int& x,int y)->void{ x=x<y?y:x; };
auto ckmin=[](int& x,int y)->void{ x=x<y?x:y; };
} using namespace IO; const int NN=2010,mod=1e9+7;
int T,n,m,q,lft[NN][NN],dwn[NN][NN];
int f[NN][NN],g[NN][NN],nxt[NN][NN];
int mx,sm;
struct matrix{
int r1,r2,c1,c2;
}t[500010]; struct QUEUE{
int pos,head,tail,cnt,q[NN];
bool type;
void check_head(){
if(head==tail){ cnt=0; return; }
if(type){
if(f[q[head]][pos]==f[q[head+1]][pos]) (cnt+=mod-g[q[head]][pos])%=mod;
else{
cnt=0;
for(int i=head+1;f[q[i]][pos]==f[q[head+1]][pos]&&i<=tail;++i) (cnt+=g[q[i]][pos])%=mod;
}
} else{
if(f[pos][q[head]]==f[pos][q[head+1]]) (cnt+=mod-g[pos][q[head]])%=mod;
else{
cnt=0;
for(int i=head+1;f[pos][q[i]]==f[pos][q[head+1]]&&i<=tail;++i) (cnt+=g[pos][q[i]])%=mod;
}
}
}
void check_tail(int a){
if(type) (cnt+=mod+g[q[tail]][pos]*(f[q[tail]][pos]==f[q[head]][pos])*a)%=mod;
else (cnt+=mod+g[pos][q[tail]]*(f[pos][q[tail]]==f[pos][q[head]])*a)%=mod;
}
void poph(){ check_head(); ++head; }
void popt(){ check_tail(-1); --tail; }
void clear(){ head=1; tail=cnt=0; }
void push(int a){ q[++tail]=a; check_tail(1); }
bool empty(){ return head>tail; }
int front(){ return head>tail?0:q[head]; }
int back(){ return head>tail?0:q[tail]; }
int sum(){ return cnt; }
}r[NN],c[NN]; int getx(int x,int y){ return nxt[x][y]==x?x:nxt[x][y]=getx(nxt[x][y],y); }
int gety(int x,int y){ return nxt[x][y]==y?y:nxt[x][y]=gety(x,nxt[x][y]); }
void init(){
mx=sm=0;
for(int i=1;i<=n;i++) r[i].clear();
for(int i=1;i<=m;i++) c[i].clear();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
lft[i][j]=dwn[i][j]=2e9,f[i][j]=g[i][j]=0;
sort(t+1,t+q+1,[](matrix a,matrix b)->bool{ return a.r1<b.r1; });
for(int i=1;i<=n+1;i++) for(int j=1;j<=m+1;j++) nxt[i][j]=i;
for(int i=1;i<=q;i++)
for(int j=t[i].c1+1;j<=t[i].c2;j++)
for(int k=getx(t[i].r1+1,j);k<=t[i].r2;k=getx(k+1,j))
lft[k][j]=t[i].r1, nxt[k][j]=getx(k+1,j); sort(t+1,t+q+1,[](matrix a,matrix b)->bool{ return a.c1<b.c1; });
for(int i=1;i<=n+1;i++) for(int j=1;j<=m+1;j++) nxt[i][j]=j;
for(int i=1;i<=q;i++)
for(int j=t[i].r1+1;j<=t[i].r2;j++)
for(int k=gety(j,t[i].c1+1);k<=t[i].c2;k=gety(j,k+1))
dwn[j][k]=t[i].c1, nxt[j][k]=gety(j,k+1);
// for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)write(lft[i][j],j==m?'\n':' '); puts("");
// for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)write(dwn[i][j],j==m?'\n':' ');
} signed main(){
freopen("roche.in","r",stdin);
freopen("roche.out","w",stdout);
T=read();
for(int i=1;i<=2000;i++)
r[i].pos=c[i].pos=i,r[i].type=0,c[i].type=1;
while(T--){
n=read(); m=read(); q=read();
for(int i=1;i<=q;i++)
t[i].r1=read(),t[i].c1=read(),t[i].r2=read(),t[i].c2=read();
init();
for(int i=1;i<=n;i++) f[i][1]=g[i][1]=1;
for(int i=1;i<=m;i++) f[1][i]=g[1][i]=1;
for(int i=2;i<=n;i++) for(int j=2;j<=m;j++){
while(!r[i-1].empty()&&f[i-1][r[i-1].back()]<f[i-1][j-1]) r[i-1].popt();
r[i-1].push(j-1);
while(!r[i-1].empty()&&r[i-1].front()<dwn[i][j]) r[i-1].poph();
f[i][j]=f[i-1][r[i-1].front()]+1; g[i][j]=max(r[i-1].sum(),1ll);
while(!c[j-1].empty()&&f[c[j-1].back()][j-1]<f[i-2][j-1]) c[j-1].popt();
c[j-1].push(i-2);
while(!c[j-1].empty()&&c[j-1].front()<lft[i][j]) c[j-1].poph();
if(f[i][j]==f[c[j-1].front()][j-1]+1) (g[i][j]+=c[j-1].sum())%=mod;
else if(f[i][j]<f[c[j-1].front()][j-1]+1) f[i][j]=f[c[j-1].front()][j-1]+1, g[i][j]=c[j-1].sum();
}
// puts("");
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
if(mx<f[i][j]) mx=f[i][j],sm=g[i][j];
else if(mx==f[i][j]) (sm+=g[i][j])%=mod;
// if(f[i][j]>1)cout<<i<<' '<<j<<' '<<f[i][j]<<' '<<g[i][j]<<endl;
}
write(mx,' '); write(sm,'\n');
}
return 0;
}
/*
1
10 7 4
7 6 10 7
3 1 5 2
7 5 10 5
3 4 3 6 */


T2 特立独行的图

分析一波发现合法的图是二分图加一个可能不存在的三元环。令值域为\([-l,l]\),那么二分图的两个部分别为正数和负数,三元环由\(0,l,-l\)组成。

找到二分图后判断两个部中的点连接的点是否构成包含关系,如果构成则可以构造。构造就一个一个加即可。

不知道为啥T了

\(code:\)

T2

#include<bits/stdc++.h>
#define nxt goto FAIL
using namespace std; namespace IO{
typedef long long LL;
auto read=[]()->int{
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
};
auto write=[](LL x,int sp)->void{
char ch[20]; int len=0;
if(x<0){ x=~x+1; putchar('-'); }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
};
auto ckmax=[](int& x,int y)->void{ x=x<y?y:x; };
auto ckmin=[](int& x,int y)->void{ x=x<y?x:y; };
} using namespace IO; const int NN=1010,MM=1000010;
int T,n,m,idx,to[MM],nex[MM],head[NN],deg[NN],col[NN];
int cnt,tim,r[NN],ans[NN];
int zero,ob,ng,tot;
bool stop;
bitset<NN> S[NN];
void add(int a,int b){
to[++idx]=b; nex[idx]=head[a]; head[a]=idx; ++deg[a]; S[a].set(b);
to[++idx]=a; nex[idx]=head[b]; head[b]=idx; ++deg[b]; S[b].set(a);
}
void clear(){
idx=stop=zero=ob=ng=tot=tim=cnt=0;
for(int i=1;i<=n;i++) S[i].reset();
memset(col,0,sizeof(col));
memset(deg,0,sizeof(deg));
memset(ans,0,sizeof(ans));
memset(head,0,sizeof(head));
} void dfs(int s,int c){
if(stop) return;
col[s]=c;
for(int i=head[s];i;i=nex[i])
if(!col[to[i]]) dfs(to[i],c^1);
else if(col[to[i]]==col[s]) stop=1;
} signed main(){
freopen("graph.in","r",stdin);
freopen("graph.out","w",stdout);
T=read();
while(T--){
n=read(); m=read(); clear();
for(int i=1;i<=m;i++) add(read(),read());
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=nex[j]) if(to[j]>i)
for(int k=head[to[j]];k;k=nex[k]) if(to[k]>to[j]&&S[i][to[k]])
col[i]=col[to[j]]=col[to[k]]=1;
for(int i=1;i<=n;i++) if(col[i]){
zero=ob; ob=ng; ng=i;
++tot;
if(tot>3) nxt;
}
if(tot){
if(deg[ob]==2) swap(zero,ob);
if(deg[ng]==2) swap(zero,ng);
if(deg[zero]!=2) nxt;
col[ng]=col[ob]=0;
}
for(int i=1;i<=n;i++) if(!col[i]) dfs(i,2);
if(stop) nxt;
for(int i=1;i<=n;i++) if(col[i]==2) r[++cnt]=i;
if(tot){
for(int i=head[ng];i;i=nex[i])
if(col[to[i]]==3){ swap(ng,ob); break; }
for(int i=head[ng];i;i=nex[i])
if(col[to[i]]==3) nxt;
for(int i=head[ob];i;i=nex[i])
if(col[to[i]]==2) nxt;
if(deg[ng]!=cnt+1||deg[ob]!=n-cnt) nxt;
ans[ng]=-1e9;
}
sort(r+1,r+cnt+1,[](int a,int b)->bool{ return deg[a]<deg[b]||b==ob; });
for(int i=1;i<cnt;i++)
if((S[r[i]]|S[r[i+1]])!=S[r[i+1]]) nxt;
for(int i=1;i<=cnt;i++){
for(int j=head[r[i]];j;j=nex[j])
if(ans[to[j]]==0) ans[to[j]]=++tim-1e9;
ans[r[i]]=++tim;
} ans[ob]=1e9; ans[zero]=0;
puts("Yes");
write(2e9,' ');
for(int i=1;i<=n;i++) write(ans[i],i==n?'\n':' ');
continue;
FAIL: puts("No");
}
return 0;
}


T3 游戏

不会数学。

T4 骆驼

不知道怎么证明,反正在\(5\times5\)的图中总能从任意一点出发,经过所有点后到达任意一点。同时也存在从\((1,1)\)出发,不经过\((3,3)\)和从\((1,1)\)出发,不经过\((3,3),(5,5)\)的情况。

于是将矩形分割为若干个\(5\times5\)的小矩形,构造方案即可。

贴个学长题解

\(code:\)

T4

#include<bits/stdc++.h>
using namespace std; namespace IO{
typedef long long LL;
auto read=[]()->int{
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
};
auto write=[](LL x,int sp)->void{
char ch[20]; int len=0;
if(x<0){ x=~x+1; putchar('-'); }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
};
auto ckmax=[](int& x,int y)->void{ x=x<y?y:x; };
auto ckmin=[](int& x,int y)->void{ x=x<y?x:y; };
} using namespace IO; const int NN=1010;
const int dx[9]={0,-3,0,0,3,2,2,-2,-2};
const int dy[9]={0,0,-3,3,0,2,-2,2,-2};
int n,m,t,endt,tim[6][6],ans[NN][NN];
int st[6][6],dn[6][6],up[6][6],lf[6][6],rt[6][6],ed[6][6];
bool stop; void dfs(int x,int y,int endx,int endy,int lmtx,int lmty,int t){
if(stop) return;
tim[x][y]=t;
if(t==endt){
if(x!=endx||y!=endy) return tim[x][y]=0,void();
return stop=1,void();
}
for(int i=1;i<=8;i++){
int tx=x+dx[i],ty=y+dy[i];
if(tx<=0||tx>5||ty<=0||ty>5||tim[tx][ty]) continue;
if(tx==lmtx&&ty==lmty) continue;
dfs(tx,ty,endx,endy,lmtx,lmty,t+1);
if(stop) return;
}
tim[x][y]=0;
} void DFS(int x,int y,int endx,int endy,int lmtx,int lmty,int t){
if(stop) return;
st[x][y]=t;
if(t==endt){
if(x!=endx||y!=endy) return st[x][y]=0,void();
return stop=1,void();
}
for(int i=1;i<=8;i++){
int tx=x+dx[i],ty=y+dy[i];
if(tx<=0||tx>5||ty<=0||ty>5||st[tx][ty]) continue;
if((tx==lmtx&&ty==lmty)||(tx==5&&ty==5)) continue;
DFS(tx,ty,endx,endy,lmtx,lmty,t+1);
if(stop) return;
}
st[x][y]=0;
} void color_it(int x,int y,int tmp[6][6],int T){
x=(x-1)*5; y=(y-1)*5;
for(int i=1;i<6;i++)
for(int j=1;j<6;j++)
ans[x+i][y+j]=tmp[i][j]+T;
} void init(){
if(m==1){
endt=25; dfs(1,1,3,3,0,0,1);
for(int i=1;i<6;i++) for(int j=1;j<6;j++)
write(tim[i][j],j==5?'\n':' ');
exit(0);
}
memset(tim,0,sizeof(tim)); endt=24; t=stop=0; dfs(1,1,5,3,3,3,1); memcpy(st,tim,sizeof(tim));
memset(tim,0,sizeof(tim)); endt=25; t=stop=0; dfs(3,3,5,3,0,0,1); memcpy(dn,tim,sizeof(tim));
memset(tim,0,sizeof(tim)); endt=25; t=stop=0; dfs(3,3,1,3,0,0,1); memcpy(up,tim,sizeof(tim));
memset(tim,0,sizeof(tim)); endt=25; t=stop=0; dfs(3,3,3,1,0,0,1); memcpy(lf,tim,sizeof(tim));
memset(tim,0,sizeof(tim)); endt=25; t=stop=0; dfs(3,3,3,5,0,0,1); memcpy(rt,tim,sizeof(tim));
memset(tim,0,sizeof(tim)); endt=25; t=stop=0; dfs(3,3,2,2,0,0,1); memcpy(ed,tim,sizeof(tim));
if(m&1) memset(st,0,sizeof(st)),endt=23, t=stop=0, DFS(1,1,5,3,3,3,1);
t=(m&1)?-2:-1; color_it(1,1,st,0); ans[3][3]=n*n;
if(m&1) ans[5][5]=n*n-1;
} signed main(){
freopen("camel.in","r",stdin);
freopen("camel.out","w",stdout);
n=read(); m=n/5;
init();
for(int i=2;i<m;i++) color_it(i,1,dn,(t+=25));
color_it(m,1,rt,(t+=25));
for(int i=m;i>1;i--){
for(int j=2;j<m;j++) color_it(i,j,rt,(t+=25));
color_it(i,m,up,(t+=25)); --i;
if((m&1)&&i==2) break;
for(int j=m;j>2;j--) color_it(i,j,lf,(t+=25));
color_it(i,2,(i==1&&!(m&1))?lf:up,(t+=25));
}
if(m&1){
for(int i=m;i>2;i-=2){
color_it(2,i,up,(t+=25));
color_it(1,i,lf,(t+=25));
if(i==3) break;
color_it(1,i-1,dn,(t+=25));
color_it(2,i-1,lf,(t+=25));
}
color_it(1,2,dn,(t+=25));
color_it(2,2,ed,(t+=25));
}
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
write(ans[i][j],j==n?'\n':' ');
// for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)printf("%4d",ans[i][j]);puts("");}
return 0;
}


最新文章

  1. VS2015 出现 .NETSystem.Runtime.Remoting.RemotingException: TCP 错误
  2. 记录自己在使用Bootstrap中的心得
  3. 夺命雷公狗---linux之centos的安装
  4. Android多媒体-人脸识别
  5. Codeforces 23E Tree
  6. Azure 网站和通配符域
  7. Camera.ScreenPointToRay 解析
  8. Linux笔记(九) - 软件包管理
  9. web项目中图标的前端处理方案
  10. 2017(4)数据库系统,分布式数据库,NoSQL,反规范化
  11. 一个axios的简单教程
  12. CentOS5/6/7系统下搭建安装Amabari大数据集群时出现SSLError: Failed to connect. Please check openssl library versions.错误的解决办法(图文详解)
  13. 大众点评Cat--架构分析
  14. mapreduce 多种输入
  15. Java虚拟机运行时数据区
  16. DbVisualizer 连接 SQL Server 2008配置
  17. 【HEOI 2018】制胡窜
  18. Ural Sport Programming Championship 2015
  19. kibana查询语法
  20. 第01章 开发准备(对最新版的RN进行了升级)1-2+项目技术分解

热门文章

  1. JDK7&amp;JDK9处理异常新特性
  2. Android使用百度语音识别api代码实现。
  3. 288 day05_异常,线程
  4. 进程代数CSP基础知识总结(Communicating sequencing process)
  5. PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作
  6. Java面向对象系列(4)- 类与对象的创建
  7. Linux文件(夹)属性与权限
  8. 大前端快闪二:react开发模式 一键启动多个服务
  9. 三千字介绍Redis主从+哨兵+集群
  10. excel模板数据填充 :tablefill