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. Vue中使用 iview 之-踩坑日记

    导航列表: 一.iview单选框Select验证问题 二.iview表单v-if引起的问题 三.Upload 手动上传组件 使用是出现的问题 四.Tabs嵌套使用时的问题 五.Tooltip 换行问题 ...

  2. WPF 通过进程实现异常隔离的客户端

    当 WPF 客户端需要实现插件系统的时候,一般可以基于容器或者进程来实现.如果需要对外部插件实现异常隔离,那么只能使用子进程来加载插件,这样插件如果抛出异常,也不会影响到主进程.WPF 元素无法跨进程 ...

  3. 解决dede编辑器不能保存word文档样式问题

    ckeditor在dede里不能保存样式,试过多种解决办法都还是没有解决.最终将编辑器换成FCK得到解决. 第一步:下载FCK编辑器 下载地址: 链接: http://pan.baidu.com/s/ ...

  4. Docker系列(22)- DockerFile指令说明并构建自己的centos

    DockerFile常用指令 实战测试 DockerHub中99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行构建 #创建一个自己的centos # 1.编写D ...

  5. jmeter 脚本录制方式详解

    关于jmeter脚本录制方式,主要分为第三方工具录制.jmeter本身代理方式录制以及人为手写脚本的三种方式.其中第三方工具录制主要有3种主流工具进行录制,badboy   BlazeMeter    ...

  6. 停止:service jenkins stop,提示:Failed to stop jenkins.service: Unit jenkins.service not loaded.

    uni@uni-virtual-machine:~$ service jenkins stop Failed to stop jenkins.service: Unit jenkins.service ...

  7. ~/.emacs emacs 配置文件

    windows ~/.emacs (when (>= emacs-major-version 24) (require 'package) (add-to-list 'package-archi ...

  8. phpstorm 配置Psr4 风格代码

    http://www.cnblogs.com/xp796/p/6441700.html

  9. CF573D-Bear and Cavalry【动态dp】

    正题 题目链接:https://www.luogu.com.cn/problem/CF573D 题目大意 给出\(n\)个人\(n\)匹马,每个人/马有能力值\(w_i\)/\(h_i\). 第\(i ...

  10. CF891E-Lust【EGF】

    正题 题目链接:https://www.luogu.com.cn/problem/CF891E 题目大意 \(n\)个数字的一个序列\(a_i\),每次随机选择一个让它减去一.然后贡献加上所有其他\( ...