[BJOI2016]水晶 做题心得
[BJOI2016]水晶 做题心得
这是一个写了我两小时的傻逼题。写这个题浪费了一堆时间后,我才意识到我码力又不行了。于是整理起了实现技巧,开始练码力。
思路
不难。首先把 \((x,y,z)\) 变成 \((x-z,y-z)\)。因为发现 \((x,y,z)\) 同时减去某个数表示的位置不变,同时减去 \(z\),把坐标只用 \(x,y\) 来描述。
发现是关于点权的,先把每个点拆成入点和出点,连一条边表示它的点权。假设入,出点分别是 \(a_i,a_o\)
然后枚举一下每个三角形,每个直线,假设是 \((a,b,c)\)。
那么这样连边:
\(S \xrightarrow[INF]{} a_i \xrightarrow[val_a]{} a_o \xrightarrow[INF]{} b_i\xrightarrow[val_b]{} b_o\xrightarrow[INF]{} c_i\xrightarrow[val_c]{}c_o\xrightarrow[INF]{} T\)
实现问题&改进
发现这样连边会连出环来。解法是,考虑按 \((x+y)\%3\) 分类,强行钦定某个顺序。这样就不会产生环了。
分开考虑三角形和直线太麻烦了,而且非常容易写错。我因此写错了 \(114514\) 次。事实上可以一块考虑,对于每个\((x+y)\%3=0\) 的,考虑它的“六周” (“四周”这个词在本题中的引申,注意到相邻的有六个点),不能有相邻的 \(\%3=1\) 和 \(\%3=2\) 的。
然后可以这样建,\(\%3=1\) 的接 \(S\),\(\%3=2\) 的接 \(T\),\(\%3=0\) 的,向周围的 \(\%3=2\) 的连一条,然后周围 \(\%3=1\) 的向它来连一条,就可以完成建图了这样结构更加清楚,简单,不容易写挂
(是参考了一篇题解中的实现
代码
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 400005
#define INF 600000000
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define MEM(x,a) memset(x,a,sizeof(x))
#define Tra(i,u) for(int i=G.st(u),v=G.to(i);~i;i=G.nx(i),v=G.to(i))
#define p_b push_back
#define sz(a) ((int)a.size())
#define all(a) a.begin(),a.end()
#define iter(a,p) (a.begin()+p)
int I() {char c=getchar(); int x=0; int f=1; while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return ((f==1)?x:-x);}
template <typename T> void Rd(T& arg){arg=I();}
template <typename T,typename...Types> void Rd(T& arg,Types&...args){arg=I(); Rd(args...);}
void RA(int *p,int n) {F(i,1,n) *p=I(),++p;}
int n;
int x[N],y[N],c[N];
map<pair<int,int>,int> rec,rid;
#define rc(x,y) rec[make_pair(x,y)]
#define ri(x,y) rid[make_pair(x,y)]
void Input()
{
n=I();
F(i,1,n)
{
int z; Rd(x[i],y[i],z,c[i]); c[i]*=10;
x[i]-=z; y[i]-=z;
if ((x[i]+y[i])%3==0) c[i]+=c[i]/10;
rc(x[i],y[i])+=c[i];
}
}
class NetworkFlow
{
public:
int S,T,n;
struct edge
{
int v,c,nx;
}pool_e[4000000+2]; edge *e;
int pool_h[N+2]; int *head;
int pool_c[N+2]; int *cur;
int ecnt=-1;
void clear()
{
ecnt=-1;
MEM(pool_e,-1); e=pool_e+2;
MEM(pool_h,-1); head=pool_h+2;
MEM(pool_c,-1); cur=pool_c+2;
// 允许 [-1]的访问
}
void add(int u,int v,int c)
{
e[++ecnt]={v,c,head[u]}; head[u]=ecnt;
}
void addflow(int u,int v,int c)
{
// printf("flow %d %d %d\n",u,v,c);
add(u,v,c);
add(v,u,0);
}
int& st(int u) {return head[u];}
int& cu(int u) {return cur[u];}
int& to(int i) {return e[i].v;}
int& cap(int i) {return e[i].c;}
int& nx(int i) {return e[i].nx;}
#define Trah(i,u) for(int i=st(u),v=to(i);~i;i=nx(i),v=to(i))
#define Trac(i,u) for(int &i=cu(u),v=to(i);~i;i=nx(i),v=to(i))
queue<int> Q;
int dep[N];
bool BFS()
{
while(!Q.empty()) Q.pop(); F(i,1,n) dep[i]=INF;
dep[S]=1; cur[S]=head[S]; Q.push(S);
while(!Q.empty())
{
int u=Q.front(); Q.pop();
if (u==T) return true;
Trah(i,u) if (cap(i) and dep[v]==INF)
{
dep[v]=dep[u]+1;
cur[v]=head[v];
Q.push(v);
}
}
return false;
}
int DFS(int u,int flow)
{
if (u==T) return flow;
int ans=0;
Trac(i,u)
{
if (!flow) break;
if (cap(i) and dep[v]==dep[u]+1)
{
int f=DFS(v,min(flow,cap(i)));
if (!f)
{
dep[v]=INF;
}
else
{
cap(i)-=f; cap(i^1)+=f;
flow-=f; ans+=f;
}
}
}
return ans;
}
int Dinic()
{
int ans=0;
while(BFS()) ans+=DFS(S,INF);
return ans;
}
NetworkFlow() {clear();}
NetworkFlow(int s,int t,int nn) {clear(); S=s; T=t; n=nn;}
}Nt;
int tot=0,S=1,T=2;
int in[N],out[N];
void Sakuya()
{
int point=0;
tot=2;
F(i,1,n) c[i]=x[i]=y[i]=0;
for(auto p:rec)
{
int i=p.first.first,j=p.first.second;
++point;
x[point]=i;
y[point]=j;
c[point]=rc(i,j);
ri(i,j)=point;
in[point]=++tot;
out[point]=++tot;
}
Nt=NetworkFlow(S,T,tot);
F(i,1,point)
{
int t=((x[i]+y[i])%3+3)%3;
if (t==1) Nt.addflow(S,in[i],INF);
if (t==2) Nt.addflow(out[i],T,INF);
else
{
int nx;
nx=ri(x[i]-1,y[i]-1); if (nx) Nt.addflow(out[nx],in[i],INF);
nx=ri(x[i]+1,y[i]); if (nx) Nt.addflow(out[nx],in[i],INF);
nx=ri(x[i],y[i]+1); if (nx) Nt.addflow(out[nx],in[i],INF);
nx=ri(x[i]+1,y[i]+1); if (nx) Nt.addflow(out[i],in[nx],INF);
nx=ri(x[i]-1,y[i]); if (nx) Nt.addflow(out[i],in[nx],INF);
nx=ri(x[i],y[i]-1); if (nx) Nt.addflow(out[i],in[nx],INF);
}
Nt.addflow(in[i],out[i],c[i]);
}
int sum=0; F(i,1,point) sum+=c[i];
int ans=sum-Nt.Dinic();
printf("%d.%d\n",ans/10,ans%10);
}
void IsMyWife()
{
Input();
Sakuya();
}
}
#undef int //long long
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();
return 0;
}
后记:两种实现的比较
原实现长达 \(220\) 行,改进实现只有 \(182\) 行。
原实现(提到过)WA了 \(114514\) 次,最高拿了 \(35\),到现在还不知道问题在哪,没调出来,也不想调了,nmsl (暴躁)
相比较改进实现一遍就A了。
所以说,码力的提升还是很重要的。
[BJOI2016]水晶 做题心得的更多相关文章
- [JSOI2019]节日庆典 做题心得
[JSOI2019]节日庆典 做题心得 一个性质有趣的字符串题 这要是在考场上我肯定做不出来吧 一开始还以为要 SAM 什么的暴力搞,没想到只用到了 \(Z\) 函数 -- 也是我生疏了罢 (学了啥忘 ...
- CF1416D 做题心得
CF1416D 做题心得 上次在某trick中提到了这个题,一开始觉得太毒瘤没有写,现在把它补上了. 感觉实现这个东西,比单纯收获一个trick,收获的东西多太多了. 主要思路 它的主要trick是& ...
- [NOIP补坑计划]NOIP2017 题解&做题心得
终于做完了…… 场上预计得分:?(省一分数线:295) 由于看过部分题解所以没有预计得分qwq 题解: D1T1 小凯的疑惑 题面 震惊!一道小学奥数题竟难倒无数高中考生! 欢迎大家以各种姿势*和谐* ...
- [NOIP补坑计划]NOIP2016 题解&做题心得
感觉16年好难啊QAQ,两天的T2T3是不是都放反了啊…… 场上预计得分:100+80+100+100+65+100=545(省一分数线280) ps:loj没有部分分,部分分见洛咕 题解: D1T1 ...
- [NOIP补坑计划]NOIP2015 题解&做题心得
感觉从15年开始noip就变难了?(虽然自己都做出来了……) 场上预计得分:100+100+60~100+100+100+100=560~600(省一分数线365) 题解: D1T1 神奇的幻方 题面 ...
- [NOIP补坑计划]NOIP2013 题解&做题心得
场上预计得分:100+100+100+100+100+60=560(省一分数线410) 五道傻逼题+一道大搜索题…… 题解: D1T1 转圈游戏 题面 水题送温暖~ #include<algor ...
- [NOIP补坑计划]NOIP2012 题解&做题心得
场上预计得分:100+90+70+100+100+3060=490520(省一分数线245) 题解: D1T1 Vigenère 密码 题面 水题送温暖~~ #include<iostream& ...
- [NOIP补坑计划]NOIP2014 题解&做题心得
六道普及组题,没啥好说的 场上预计得分:100+100+100+100+100+100=600(省一分数线490) (AK是不可能AK的,这辈子不可能AK的) 题解: D1T1 生活大爆炸版石头剪刀布 ...
- 标 题: [心得]传统IT转互联网面试经验分享
发信人: lgonnet (逃之夭夭), 信区: Java标 题: [心得]传统IT转互联网面试经验分享发信站: 水木社区 (Wed Jul 1 10:18:38 2015), 站内 统一回复一下 ...
随机推荐
- JAVA中IO流详解
IO流:数据传输是需要通道的,而IO流就是数据传输的通道. IO流可以形象的比喻为运送货物的传输带. IO流的分类: ①根据操作的数据类型的不同可以分为 :字节流与字符流. ②根据数据的流向分为:输入 ...
- [leetcode]236. Lowest Common Ancestor of a Binary Tree树的最小公共祖先
如果一个节点的左右子树上分别有两个节点,那么这棵树是祖先,但是不一定是最小的,但是从下边开始判断,找到后一直返回到上边就是最小的. 如果一个节点的左右子树上只有一个子树上遍历到了节点,那么那个子树可能 ...
- HTTP 常用状态码200 301 302 403 500
200(OK):成功处理了请求. 301 redirect: 301 代表永久性转移(Permanently Moved) //助记 1 永恒,如果你记住了这一条就算这篇博客没白写.302 redir ...
- ASP.NET Core路由中间件[1]: 终结点与URL的映射
目录 一.路由注册 二.设置内联约束 三.默认路由参数 四.特殊的路由参数 借助路由系统提供的请求URL模式与对应终结点(Endpoint)之间的映射关系,我们可以将具有相同URL模式的请求分发给应用 ...
- QtCreator使用技巧
快捷键 "F4" 在同名的头文件和源程序文件之间切换 "F2" 跟踪光标下的符号,若是变量,可以跟踪到变量声明的地方:若是函数体或函数声明,可以在两者之间切换. ...
- 项目实战--@Transactional 的使用
@Transactional 介绍 Spring 事务管理分为编码式和声明式的两种方式,编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP,将具体业务逻辑与事务处理解耦.@Transacti ...
- [每日一题]面试官问:谈谈你对ES6的proxy的理解?
[每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- netty启动流程
本文通过对netty服务端.客户端的启动流程分析, 让大家对netty是如何启动运行的. 废话不多说,上源码!!! 建议读者学习netty下的jar类型为 netty-example,里面有很多exa ...
- Face_to_object_design
二.实例 掷骰子游戏:三粒骰子,掷两次,比较两次的结果. 1.提炼 提炼对象:三粒骰子.游戏 提炼对象的属性和功能:掷骰子.比较点数 骰子: 属性:点数 功能:随机获取一个1~6之间的整数值. 游戏: ...
- 了解一下IO控制器与控制方式
IO控制器 CPU无法直接控制IO设备的机械部件,因此IO设备还要有个电子部件作为CPU和IO设备机械部件之间的"中介",用于实现CPU对设备的控制. 这个电子部件就是IO控制器, ...