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;
}


2021.10.18考试总结[NOIP模拟76]的更多相关文章

  1. 2021.10.9考试总结[NOIP模拟72]

    T1出了个大阴间题 状压\(DP\),记当前状态的代价和与方案数.状态\(\Theta(2^nn)\),转移\(\Theta(n)\). 发现每个状态的最大值只会是所选集合的\(max\)或加一.于是 ...

  2. 2021.10.15考试总结[NOIP模拟77]

    \(n=40\)考虑\(meet \;in \;the \;middle\) 某个元素有关的量只有一个时考虑转化为树上问题 对暴力有自信,相信数据有梯度 没了 UPD:写了个略说人话的. T1 最大或 ...

  3. 2021.10.12考试总结[NOIP模拟75]

    T1 如何优雅的送分 考虑式子的实际意义.\(2^{f_n}\)实际上就是枚举\(n\)质因子的子集.令\(k\)为这个子集中数的乘积,就可以将式子转化为枚举\(k\),计算\(k\)的贡献. 不难得 ...

  4. 2021.10.11考试总结[NOIP模拟74]

    T1 自然数 发现\(mex\)是单调不降的,很自然地想到用线段树维护区间端点的贡献. 枚举左端点,用线段树维护每个右端点形成区间的\(mex\)值.每次左端点右移相当于删去一个数. 记\(a_i\) ...

  5. 2021.10.7考试总结[NOIP模拟71]

    信心赛,但炸了.T3SB错直接炸飞,T4可以硬算的组合数非要分段打表求阶乘..T2也因为一个细节浪费了大量时间.. 会做难题很好,但首先还是要先把能拿的分都拿到. T1 签到题 结论:总可以做到对每个 ...

  6. 2021.9.18考试总结[NOIP模拟56]

    T1 爆零 贪心地想,肯定要先走完整个子树再走下一个,且要尽量晚地走深度大的叶子.所以对每个点的儿子以子树树高为关键字排序$DFS$即可. 也可$DP$. $code:$ T1 #include< ...

  7. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  8. 2021.8.3考试总结[NOIP模拟29]

    T1 最长不下降子序列 数据范围$1e18$很不妙,但模数$d$只有$150$,考虑从这里突破. 计算的式子是个二次函数,结果只与上一个值有关,而模$d$情况下值最多只有$150$个,就证明序列会出现 ...

  9. 2021.6.29考试总结[NOIP模拟10]

    T1 入阵曲 二位前缀和暴力n4可以拿60. 观察到维护前缀和时模k意义下余数一样的前缀和相减后一定被k整除,前缀和维护模数,n2枚举行数,n枚举列, 开一个桶记录模数出现个数,每枚举到该模数就加上它 ...

随机推荐

  1. Spring系列之集成MongoDB的2种方法

    MongoDB是最流行的NoSQL数据库,SpringBoot是使用Spring的最佳实践.今天带大家讲一讲SpringBoot集成MongoDB的两种方式,MongoDB的安装自行去官网查询,本地开 ...

  2. 【Nginx】Linux常用命令------启动、停止、重启

    启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /us ...

  3. STM32CbueIDE 体验

    STM32CbueIDE 体验 下载安装 官网下载链接:https://www.st.com/zh/development-tools/stm32cubeide.html. 软件启动时会令设置工作目录 ...

  4. 使用 VSCode 开发调试 STM32 单片机尝试

    使用 VSCode 开发调试 STM32 单片机尝试 本文记录基于 Windows + DAP-Link 开发 STM32F103C8T6 的实践过程,其他操作系统或芯片应该也只是大同小异的问题. 注 ...

  5. PHP的bz2压缩扩展工具

    在日常的开发和电脑使用中,我们经常会接触到压缩和解压的一些工具,PHP 也为我们准备了很多相关的操作扩展包,都有直接可用的函数能够方便的操作一些压缩解压功能.今天,我们先学习一个比较简单但不太常用的压 ...

  6. PHP匿名类的用法

    在PHP7之后,PHP中加入了匿名类的特性.匿名类和匿名方法让PHP成为了更现代化的语言,也让我们的代码开发工作越来越方便.我们先来看看匿名类的简单使用. // 直接定义 $objA = new cl ...

  7. Linux系列(24) - chmod

    前言 在Unix和Linux的中,每个文件(文件夹也被看作是文件)都有三种权限:读.写.运行. 被授予权限的用户身份有三种:当前文件的拥有者,与拥有者属于同组者(同一个group),其他人 hello ...

  8. 版本管理 - Git 使用入门

    Git 是一个分布式的版本管理系统,而 SVN 是一个集中式管理系统. 版本控制 Git与SVN的对比 对比 SVN Git 工作方式 集中式 分布式 文件管理 增量式 系统快照 权限控制 对团队中参 ...

  9. supervisor + celery 的简单配置与报错处理

    ubuntu服务器下使用 supervisor 和 celery supervisor 的卸载过程: sudo apt purge supervisor whereis supervisord如果有用 ...

  10. Python3入门系列之-----file方法操作

    file方法 file处理文件的一些方法,创建一个file对像后即可对文件进行读写相关操作,首先你得打开文件,此处用到open函数 open函数 语法:file_objcet = open(file_ ...