Postal Vans

题目大意

4*n的网格,要经过所有点的有向有环,不重复经过点的路径总数

n<=1000

题解

显然 插头dp

以4为切面

问题是,会发现 超精度

解决呢要么实现高精度,要么换python XD

c++实现 未+高精度,会爆掉

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--) using namespace std; const string filename = "vans"; void usefile(){
freopen((filename+".in").c_str(),"r",stdin);
freopen((filename+".out").c_str(),"w",stdout);
} int n; const int S1001 = 0;
const int S1122 = 1;
const int S1100 = 2;
const int S0110 = 3;
const int S0011 = 4;
const int S1221 = 5;
const int S0000 = 6; long long dp[1010][10];
int s2[10][10]; void init(){
s2[S1001][S0000] = 1;
s2[S1001][S1100] = 1;
s2[S1001][S0110] = 1;
s2[S1001][S0011] = 1;
s2[S1001][S1221] = 1; s2[S1122][S1001] = 1;
s2[S1122][S1122] = 1;
// s2[S1122][S1100] = 1; 不应该自闭
// s2[S1122][S0011] = 1; 不应该自闭
// s2[S1122][S0000] = 1; 不应该自闭 s2[S1100][S1122] = 1;
s2[S1100][S1001] = 1; s2[S0110][S1001] = 1; s2[S0011][S1122] = 1;
s2[S0011][S1001] = 1; // s2[S1221][S1001] = 1; 不应该自闭
s2[S1221][S0000] = 1;
s2[S1221][S1100] = 1;
s2[S1221][S0011] = 1;
s2[S1221][S1221] = 1;
} int main(){
usefile();
init();
cin>>n; dp[0][S1001] = 1;
dp[0][S1122] = 1;
rep(i,1,n){
rep(stateS,0,6){
rep(stateE,0,7){
if(s2[stateS][stateE]){
dp[i][stateE]+=dp[i-1][stateS];
}
}
}
}
// rep(i,0,n){
// rep(state,0,7){
// cout<<dp[i][state]<<"\t";
// }
// cout<<endl;
// }
cout<<dp[n-1][S0000]*2<<endl;
return 0;
}

增加高精度

#include <bits/stdc++.h>
typedef long long ll;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back using namespace std; const string filename = "vans"; void usefile(){
freopen((filename+".in").c_str(),"r",stdin);
freopen((filename+".out").c_str(),"w",stdout);
} class hpa{
int DIGITS = 100'000'000; // 08lld
vector<ll>vals;
public:
hpa(){
}
hpa(ll v){
vals.pb(v);
}
void print(){
if(vals.size() == 0){
printf("0");
return;
}
printf("%lld",vals[vals.size()-1]);
per(i,0,vals.size()-1){
printf("%08lld",vals[i]);
}
}
hpa operator +(const hpa &another) const {
hpa ret;
rep(i,0,vals.size()){
ret.vals.pb(vals[i]);
}
rep(i,0,another.vals.size()){
if(i >= ret.vals.size()){
ret.vals.pb(another.vals[i]);
}else{
ret.vals[i]+=another.vals[i];
if(ret.vals[i] >= DIGITS){
if(i == ret.vals.size()-1){
ret.vals.pb(0);
}
ret.vals[i+1]+=ret.vals[i]/DIGITS;
ret.vals[i]%=DIGITS;
}
}
}
return ret;
}
}; int n; const int S1001 = 0;
const int S1122 = 1;
const int S1100 = 2;
const int S0110 = 3;
const int S0011 = 4;
const int S1221 = 5;
const int S0000 = 6; hpa dp[1010][10];
int s2[10][10]; void init(){
s2[S1001][S0000] = 1;
s2[S1001][S1100] = 1;
s2[S1001][S0110] = 1;
s2[S1001][S0011] = 1;
s2[S1001][S1221] = 1; s2[S1122][S1001] = 1;
s2[S1122][S1122] = 1;
// s2[S1122][S1100] = 1; 不应该自闭
// s2[S1122][S0011] = 1; 不应该自闭
// s2[S1122][S0000] = 1; 不应该自闭 s2[S1100][S1122] = 1;
s2[S1100][S1001] = 1; s2[S0110][S1001] = 1; s2[S0011][S1122] = 1;
s2[S0011][S1001] = 1; // s2[S1221][S1001] = 1; 不应该自闭
s2[S1221][S0000] = 1;
s2[S1221][S1100] = 1;
s2[S1221][S0011] = 1;
s2[S1221][S1221] = 1;
} int main(){
usefile();
init();
cin>>n; dp[0][S1001] = 2;
dp[0][S1122] = 2;
rep(i,1,n){
rep(stateS,0,6){
rep(stateE,0,7){
if(s2[stateS][stateE]){
dp[i][stateE]=(dp[i][stateE]+dp[i-1][stateS]);
}
}
}
}
// rep(i,0,n){
// rep(state,0,7){
// cout<<dp[i][state]<<"\t";
// }
// cout<<endl;
// }
dp[n-1][S0000].print();
printf("\n");
return 0;
}

A Rectangular Barn

Mircea Pasoi -- 2003

题目大意

(<=3000)*(<=3000)的矩阵

上面有<=30000 个坏点

求 最大不含坏点的矩形面积

题解

因为求的是最大矩形,那么它的四周要么是边界,要么是坏点

证明:反证明

如果存在一条边既没有邻接 边界,也没有邻接坏点。

那么对该边延伸 ,可以得到更大的矩形,矛盾

观察到这个性质后

我们考虑对任意 点(i,j)

i0<i,其中(i0,j)为距离(i,j)最远的点 且 线段(i0->i,j)上无坏点

线(i0->i,j)为高,做横向扩张,找左右两侧的最近的坏点 或边界,则有以(i,j)搜寻的矩形面积=(i0->i,j) * 该线段左右扩张的最大宽度

  1. 这样找到的矩形 一定是 合法矩形 所以这样找到的矩形面积小于等于 最大面积
  2. 这样一定能找到最大的矩形,因为我们证明了最大矩形 一定邻接着坏点或边界,那么该最大矩形上方边界所对应的 坏点,正下方的的点 在运算过程会计算到

所以O(3000*3000),以所有点计算出一个矩形,每个矩形计算复杂度为O(1),即可

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--) using namespace std; const string filename = "rectbarn"; void usefile(){
freopen((filename+".in").c_str(),"r",stdin);
freopen((filename+".out").c_str(),"w",stdout);
} int L[3010],R[3010]; // j列当前线段 左右扩展的可行最远距离
int H[3010]; // j列 当前 的线段长度
bool g[3010][3010];
int n,m,ans;
int main(){
usefile();
freopen("rectbarn.in","r",stdin);
freopen("rectbarn.out","w",stdout);
int k;
cin>>n>>m>>k;
while(k--){
int i,j;
scanf("%d%d",&i,&j);
g[i][j]=1;
}
rep(j,0,m+1){
H[j]=0;
L[j]=1;
R[j]=m;
}
rep(i,1,n+1){
// 处理所有 坏点
rep(j,1,m+1){
if(g[i][j]){
H[j]=0;
L[j]=1;
R[j]=m;
}
}
// 计算所有 左侧 和 右侧 最远
int lm = 1;
rep(j,1,m+1){
if(!g[i][j]){
H[j]++;
L[j]=max(L[j],lm);
} else{
lm=j+1;
}
}
int rm = m;
per(j,1,m+1){
if(!g[i][j]){
R[j]=min(R[j],rm);
}else{
rm=j-1;
}
}
// 计算面积
rep(j,1,m+1){
if(!g[i][j]){
ans=max(ans,(R[j]-L[j]+1)*H[j]);
}
}
}
printf("%d\n",ans);
return 0;
}

Cow XOR

Adrian Vladu -- 2005

题目大意

n(<=100,000)个数,数值范围是[0,2^21 - 1]

求连续子区间 的最大xor值,输出 最大xor值,区间起始点,区间结束点

如果有多个区间满足最大异或,返回结束点index最小的,如果还有多个,返回长度最短的。

题解

首先

我们证明一下题目描述的结果唯一

如果多个 子区间 异或值相同,且结束点不同,那么 只有唯一可以选

如果两个 子区间 异或值相同,且结束点相同,那么 它们一定起始点不同,所以它们长度不同,只有最短可选

综上,题目描述结果唯一

然后

显然

xor[l->r] = xor[1->l-1]^xor[1->r]

所以 我们要找最大值,等于找两个前缀异或的最大值

从高位到低位,对所有前缀建立trie树,再for一遍贪心走trie树,贪心规则 有和当前位不同的走不同的路径,否则才走相同,(尽量在高位产生1)

空间 O(n*21),时间O(n*21)

空间节点数

s=0;
for i in range(0,22):
s+=min(2**i,100000)
print(s)

631071 个,然而 我开这么大会炸空间,开500000过的 (按道理讲 这样空间上看是开得有问题,开小了,不过过了测试)

我在实现过程中是找 区间左右端点靠的是 lower_bound二分,多用了空间,

然而,我们发现 最优区间必定有一个是 其前缀值的最小坐标

所以 如果枚举i去寻找 其期望的 前缀值对应的最小坐标,一定能找到最优值,可以优化

通过的,但空间开得不合理的代码,(我之前还用struct来写,虽然阅读上更好理解,但空间更加不够XD)

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--) using namespace std; const string filename = "cowxor"; void usefile(){
freopen((filename+".in").c_str(),"r",stdin);
freopen((filename+".out").c_str(),"w",stdout);
} int n;
int a[100010];
int p[100010];
int ns[500010][2]; int nsi=0; int *root = ns[nsi++]; map<int,vector<int> > pv2idx; // 前缀异或 到 下表 void build(int idx){
int v = p[idx];
pv2idx[v].push_back(idx); // ordered
int * po = root;
per(i,1,21){
int bit = !!(v&(1<<i));
if(!po[bit]){
po[bit] = nsi++;
}
po=ns[po[bit]];
}
int bit = !!(v&1);
po[bit] = v;
} int query(int idx){
int v = p[idx];
int * po = root;
per(i,1,21){
int bit = !(v&(1<<i));
if(!po[bit]){
po = ns[po[bit^1]];
}else{
po = ns[po[bit]];
}
}
int bit = !(v&1);
return po[bit] == 0?po[bit^1]:po[bit];
} int ans=-1,ansl,ansr; void setAns(int v1,int l,int r){
// cout<<"SETANS:"<<v1<<" l:"<<l<<" r:"<<r<<endl;
if(l > r){
swap(l,r);
}
if(v1 < ans)return;
if(v1 > ans){
ans = v1;
ansl = l;
ansr = r;
return ;
}
if(r < ansr){
ansl = l;
ansr = r;
return ;
}
if(r > ansr){
return ;
}
if(l > ansl){
ansl = l;
return ;
}
} int main(){
usefile();
scanf("%d",&n);
rep(i,0,n){
scanf("%d",a+i);
}
rep(i,0,n){
p[i+1]=p[i]^a[i];
}
rep(i,0,n+1){
build(i);
}
// for(auto item:pv2idx){
// cout<<"--------"<<item.first<<endl;
// for(auto z:item.second){
// cout<<z<<"\t"<<endl;
// }
// cout<<endl;
// }
rep(i,0,n+1){
int ret = query(i);
int reti = lower_bound(pv2idx[ret].begin(),pv2idx[ret].end(),i)-pv2idx[ret].begin();
// cout<<"find:"<<i<<"["<<p[i]<<"]:"<<ret<<"("<<pv2idx[ret][reti]<<")"<<endl;
if(ret == p[i]){
if(i > 0){
setAns(ret^p[i],i-1,i);
}
}else if(reti > 0){
setAns(ret^p[i],i,pv2idx[ret][reti-1]);
}else{
setAns(ret^p[i],i,pv2idx[ret][reti]);
}
}
printf("%d %d %d\n",ans,ansl+1,ansr);
return 0;
}

USACO 6.1 章节的更多相关文章

  1. USACO 6.4 章节

    The Primes 题目大意 5*5矩阵,给定左上角 要所有行,列,从左向右看对角线为质数,没有前导零,且这些质数数位和相等(题目给和) 按字典序输出所有方案... 题解 看上去就是个 无脑暴搜 题 ...

  2. USACO 6.3 章节 你对搜索和剪枝一无所知QAQ

    emmm........很久很久以前 把6.2过了 所以emmmmmm 直接跳过 ,从6.1到6.3吧 Fence Rails 题目大意 N<=50个数A1,A2... 1023个数,每个数数值 ...

  3. USACO 5.5 章节

    Picture 题目大意 IOI 1998 求n (<=5000)个矩形 覆盖的图形 的周长(包括洞), 坐标范围[-10000,10000] 题解 一眼离散化+2维线段树,但仔细一想 空间不太 ...

  4. USACO 5.4 章节

    Canada Tour 题目大意 双向连通图,点从左向右排列, 你需要先从最左的点到最右的点,(过程中只能从左向右走) 然后再从最右的点返回最左的点,(过程中只能从右向左走) 过程中除了最左的点,其它 ...

  5. USACO 5.3 章节

    相关讲解可在USACO上看原文,也可以搜索nocow找到翻译的! (nocow上有些微翻译是有问题的,如果想看nocow翻译的建议也对着英文看) 以下记录以下 自己之前未掌握的一些要点,以及按自己的括 ...

  6. USACO 6.5 章节 世界上本没有龙 屠龙的人多了也便有了

    All Latin Squares 题目大意 n x n矩阵(n=2->7) 第一行1 2 3 4 5 ..N 每行每列,1-N各出现一次,求总方案数 题解 n最大为7 显然打表 写了个先数值后 ...

  7. (Step1-500题)UVaOJ+算法竞赛入门经典+挑战编程+USACO

    http://www.cnblogs.com/sxiszero/p/3618737.html 下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年 ...

  8. 算法竞赛入门经典+挑战编程+USACO

    下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinej ...

  9. USACO . Your Ride Is Here

    Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often co ...

随机推荐

  1. MyBatis 配置/注解 SQL CRUD 经典解决方案(2019.08.15持续更新)

    本文旨在记录使用各位大神的经典解决方案. 2019.08.14 更新 Mybatis saveOrUpdate SelectKey非主键的使用 MyBatis实现SaveOrUpdate mybati ...

  2. jquery动态加载select选项

    $("#selectid").get(0).options.add(new Option(json数据))

  3. MapReduce的序列化机制

    MapReduce自己实现了一套序列化机制,通过实现Writable接口, 重写DateInput和DateOutPut方法,实现数据的序列化和反序列化, 相比于JDK自带的序列化,MapReduce ...

  4. js的label标签语句与with语句的用法

    /** * label标签语句 * - 语法: * 标签名: 语句 * 如:start: n = 1; * 上面标签start可以被之后的break或continue语句引用 * - label标签语 ...

  5. iOS crash log 解析

    iOS开发中,经常遇到App在开发及测试时不会有问题,但是装在别人的设备中会出现各种不定时的莫名的 crash,因为iOS设备会保存应用的大部分的 crash Log,所以可以通过 crash Log ...

  6. Nginx学习总结(一)

    Nginx是目前比较主流的HTTP反向代理服务器(其企业版提供了基于TCP层的反向代理插件),对于构建大型分布式web应用,具有举足轻重的作用.简单来说,nginx有2个主要的功能:动/静态资源分离. ...

  7. Python元类之由浅入深

    前言 ​ 元类属于python面向对象编程的深层次的魔法,非常重要,它使我们可以更好的掌控类从创建到消亡的整个生命周期过程.很多框架的源码中都使用到了元类.例如 Django Framework 中的 ...

  8. (ACM模板)二元组pair

    #include<iostream> #include<cstdio> #include<utility> using namespace std; typedef ...

  9. Kettle5.4.0 java.lang.OutOfMemoryError

    CPU: Intel i3 3.40GHz Memory : 8G Kettle默认配置 将MySQL上的一张29W条数据的表,通过Kettle增量抽取到Vertica数据库中,结果在排序这一步报内存 ...

  10. 使用stylelint进行Vue项目样式检查

    stylelint是一个强大的现代 CSS 检测器,可以让开发者在样式表中遵循一致的约定和避免错误.拥有超过170条的规则,包括捕捉错误.最佳实践.控制可以使用的语言特性和强制代码风格规范.它支持最新 ...