codechef Graph on a Table

https://www.codechef.com/problems/TBGRAPH

题意 :

  • 一个\(n\times m\)的网格图。\(q\) 个矩形,格子\((r1,c1)\)可以到达\((r2,c2)\)的条件是\(r2>r1,c2>c1\)且存在一个矩形同时包含这两个点。
  • 初始点任意,求最多走几步以及方案数。
  • \(T\le 100000,S=\sum nm\le 10^7,\sum q\le 500000,\ n,m\le 2000\)

分析:

  • 首先一个点\((r1,c1)\)只需要连\((r1+1,k)\)和\((k,c1+1)\)这些点,其他的点可以通过这些点到达。
  • 那么我们求出每个点向右,向下扩展的最远点,这个可以用类似扫描线的东西扫两次,用\(set\)维护每个位置的最远点,复杂度\(O(q\log q+nm)\)。
  • 然后可以\(dp\),这个\(dp\)显然可以单调队列一下,开\(m+1\)个队列即可。
  • 方案数的话在队列里进出的同时顺便用个数组维护一下就可以了。
  • 没什么意思,单纯只是代码长。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <bitset>
#include <set>
#include <iostream>
using namespace std;
typedef long long ll;
#define mod 1000000007
//n,m<=2000,q<=500000
#define N 1000050
#define M 4000050
#define db(x) cerr<<#x<<" = "<<x<<endl
int n,m,q,id[2050][2050];
int la=0,f[M],g[M];
int now[N],rt[M],dw[M],r1[N],c1[N],r2[N],c2[N];
multiset<int>St[2050];
int Q[2050],Q2[2050][2050],L[2050],R[2050];
int nowans[2050],nowans2[2050][2050];
char buf[100000],*p1,*p2;
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {
int x=0; char s=nc();
while(s<'0'||s>'9') s=nc();
while(s>='0'&&s<='9') x=(((x<<2)+x)<<1)+s-'0',s=nc();
return x;
}
struct A {
int l,r,x,o;
A() {}
A(int l_,int r_,int x_,int o_) {l=l_,r=r_,x=x_,o=o_;}
bool operator < (const A &u) const {
return x<u.x;
}
}a[N]; inline void upd(int x,int y) {
if(f[y]<f[x]+1) f[y]=f[x]+1,g[y]=g[x];
else if(f[y]==f[x]+1) g[y]=(g[y]+g[x])%mod;
}
inline void UPD(int &x,int y) {
x+=y; if(x>=mod) x-=mod;
}
int NOW;
// int ss=0,sq=0;
void solve() {
NOW++;
n=rd(),m=rd(),q=rd();
// ss+=n*m,sq+=q;
int i,j,k,ln=n*m;
int gg=0;
for(i=0;i<=ln+1;i++) f[i]=g[i]=0;
for(i=1;i<=n;i++)for(j=1;j<=m;j++)id[i][j]=++gg;
for(i=1;i<=n;i++)for(j=1;j<=m;j++)rt[id[i][j]]=j,dw[id[i][j]]=i;
for(i=1;i<=q;i++)r1[i]=rd(),c1[i]=rd(),r2[i]=rd(),c2[i]=rd();
// if(NOW==17)for(i=1;i<=q;i++) printf("%d %d %d %d\n",r1[i],c1[i],r2[i],c2[i]);
// return ;
la=0;
for(i=1;i<=q;i++) if(r1[i]!=r2[i]) {
a[++la]=A(c1[i],c2[i],r1[i],1);
a[++la]=A(c1[i],c2[i],r2[i],-1);
}
sort(a+1,a+la+1);
for(i=1;i<=m;i++) now[i]=i,St[i].clear();
j=1;
for(i=1;i<=n;i++) {
for(;j<=la&&a[j].x==i;j++) {
int x=a[j].l;
if(a[j].o==1) St[x].insert(a[j].r);
else St[x].erase(St[x].find(a[j].r));
if(!St[x].empty()) now[x]=*St[x].rbegin();
else now[x]=x;
}
for(k=1;k<=m;k++) {
rt[id[i][k]]=max(rt[id[i][k-1]],now[k]);
}
}
la=0;
for(i=1;i<=q;i++) if(c1[i]!=c2[i]) {
a[++la]=A(r1[i],r2[i],c1[i],1);
a[++la]=A(r1[i],r2[i],c2[i],-1);
}
sort(a+1,a+la+1);
for(i=1;i<=n;i++) now[i]=i,St[i].clear();
j=1;
for(i=1;i<=m;i++) {
for(;j<=la&&a[j].x==i;j++) {
int x=a[j].l;
if(a[j].o==1) St[x].insert(a[j].r);
else St[x].erase(St[x].find(a[j].r));
if(!St[x].empty()) now[x]=*St[x].rbegin();
else now[x]=x;
}
for(k=1;k<=n;k++) {
dw[id[k][i]]=max(dw[id[k-1][i]],now[k]);
}
}
for(i=1;i<=m;i++) for(j=0;j<=n;j++) nowans2[i][j]=0;
for(i=1;i<=m;i++) L[i]=R[i]=0;
for(i=1;i<=n;i++) {
int l=0,r=0;
for(j=0;j<=m;j++) nowans[j]=0;
for(j=1;j<=m;j++) {
f[id[i][j]]=1; g[id[i][j]]=1;
if(j>1) {
while(l<r&&rt[Q[l]]<j) {
UPD(nowans[f[Q[l]]],mod-g[Q[l]]);
l++;
}
if(l<r) {
f[ln+1]=f[Q[l]];
g[ln+1]=nowans[f[Q[l]]];
upd(ln+1,id[i][j]);
}
if(i>2) {
while(L[j-1]<R[j-1]&&dw[Q2[j-1][L[j-1]]]<i) {
UPD(nowans2[j-1][f[Q2[j-1][L[j-1]]]],mod-g[Q2[j-1][L[j-1]]]);
L[j-1]++;
}
if(L[j-1]<R[j-1]) {
f[ln+1]=f[ Q2[j-1][ L[j-1] ] ];
g[ln+1]=nowans2[j-1][f[ln+1]];
upd(ln+1,id[i][j]);
}
}
}
if(i>1) {
while(l<r&&f[Q[r-1]]<f[id[i-1][j]]) {
UPD(nowans[f[Q[r-1]]],mod-g[Q[r-1]]);
r--;
}
Q[r++]=id[i-1][j];
UPD(nowans[f[id[i-1][j]]],g[id[i-1][j]]);
}
upd(id[i][j],0);
}
if(i>1) {
for(j=1;j<=m;j++) {
while(L[j]<R[j]&&f[Q2[j][R[j]-1]]<f[id[i-1][j]]) {
UPD(nowans2[j][f[Q2[j][R[j]-1]]],mod-g[Q2[j][R[j]-1]]);
R[j]--;
}
Q2[j][R[j]++]=id[i-1][j];
UPD(nowans2[j][f[id[i-1][j]]],g[id[i-1][j]]);
}
}
} printf("%d %d\n",f[0]-1,g[0]);
}
// #include <ctime>
// double tt;
int main() { // freopen("roche.in","r",stdin);
// freopen("roche.out","w",stdout); // tt=clock(); int T;
scanf("%d",&T);
while(T--) solve(); // printf("%.2f\n",(clock()-tt)/1000.0);
// printf("%d %d\n",sq,ss);
}
/*
2
3 4 2
1 1 2 2
2 2 3 4
3 3 2
1 1 3 3
1 1 3 3
*/

codechef Graph on a Table的更多相关文章

  1. Emotion Recognition Using Graph Convolutional Networks

    Emotion Recognition Using Graph Convolutional Networks 2019-10-22 09:26:56 This blog is from: https: ...

  2. Grafana介绍

    Grafana是一个开源的度量分析与可视化套件.纯 Javascript 开发的前端工具,通过访问库(如InfluxDB),展示自定义报表.显示图表等.大多使用在时序数据的监控方面,如同Kibana类 ...

  3. python sqlite3 入门 (视频讲座)

    python sqlite3 入门 (视频讲座) an SQLite mini-series! - Simple Databases with Python 播放列表: YouTube https:/ ...

  4. Grafana关键词

    The open platform for beautiful analytics and monitoring. data source.panels.apps.dashboards. Organi ...

  5. 大数据技术之_19_Spark学习_05_Spark GraphX 应用解析 + Spark GraphX 概述、解析 + 计算模式 + Pregel API + 图算法参考代码 + PageRank 实例

    第1章 Spark GraphX 概述1.1 什么是 Spark GraphX1.2 弹性分布式属性图1.3 运行图计算程序第2章 Spark GraphX 解析2.1 存储模式2.1.1 图存储模式 ...

  6. 「功能笔记」性能分析工具gprof使用笔记

    根据网上信息整理所成. 功能与优劣 gprof实际上只是一个用于读取profile结果文件的工具.gprof采用混合方法来收集程序的统计信息,它使用检测方法,在编译过程中在函数入口处插入计数器用于收集 ...

  7. 1. Spark GraphX概述

    1.1 什么是Spark GraphX Spark GraphX是一个分布式图处理框架,它是基于Spark平台提供对图计算和图挖掘简洁易用的而丰富的接口,极大的方便了对分布式图处理的需求.那么什么是图 ...

  8. 大众点评cat监控平台搭建

    参考官方文档:https://github.com/dianping/cat/wiki/readme_server 1.数据库相关 (1)创建数据库cat,并执行以下sql创建相关表: CREATE ...

  9. apache-atlas 深度剖析

    atlas  是apache下的大数据的元数据管理平台,支持对hive.storm.kafka.hbase.sqoop等进行元数据管理以及以图库的形式展示数据的血缘关系. 一.架构 整体架构实现如下图 ...

随机推荐

  1. Python3.x:ConfigParser模块的使用

    Python3.x:ConfigParser模块的使用 简介 ConfigParser模块在python中是用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节 ...

  2. Python MySQL数据库连接模块

    1. MySQLdb只支持在Python 2版本使用MySQLdb是用于Python链接Mysql数据库的接口.a.pip安装 直接使用pip进行安装,在此之前需要安装一些系统依赖包. ● CentO ...

  3. Percona-Server-5.7.16 启动错误

    基于:percona-server-5.7.16 启动报错:  [root@monitor mysql]# ./bin/mysqld_safe --defaults-file=/data/config ...

  4. 华为S5700系列交换机配置通过流策略实现VLAN间三层隔离

    组网图形 图1 配置通过流策略实现VLAN间三层隔离组网图 组网需求 如图一所示,为了通信的安全性,某公司将访客.员工.服务器分别划分到VLAN10.VLAN20.VLAN30中.公司希望: 员工.服 ...

  5. Spring中Bean管理的常用注解

    在Spring中,主要用于管理bean的注解分为四大类:1.用于创建对象.2.用于给对象的属性注入值.3.用于改变作用的范围.4.用于定义生命周期.这几个在开发中经常接触到,也可以说每天都会遇见.其中 ...

  6. maven中pom.xml标签介绍

    pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述了项目:包括配置文件:开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的url,项目的依赖性,以 ...

  7. 用Java编程计算猴子吃桃问题

    猴子吃桃问题:猴子吃桃子问题:猴子第一天摘下N个桃子,当时就吃了一半,还不过瘾,就又吃了一个.第二天又将剩下的桃子吃掉一半,又多吃了一个.以后每天都吃前一天剩下的一半零一个.到第10天在想吃的时候就剩 ...

  8. ButterKnife使用详谈

    (1)ButterKnife是什么? 在开发过程中,我们总是会写大量的findViewById和点击事件,像初始view.设置view监听这样简单而重复的操作让人觉得特别麻烦,当然不会偷懒的程序员不是 ...

  9. LeetCode第[50]题(Java):Pow(x, n)

    题目:求x的n次幂 难度:Medium 题目内容: Implement pow(x, n), which calculates x raised to the power n (xn). 翻译: 实现 ...

  10. codeforces 831B. Keyboard Layouts 解题报告

    题目链接:http://codeforces.com/contest/831/problem/B 题目意思:给出两个长度为26,由小写字母组成的字符串s1和s2,对于给出的第三个字符串s3,写出对应s ...