BZOJ 2661 连连看

http://www.lydsy.com/JudgeOnline/problem.php?id=2661

思路:预处理出每个数字,然后若有x^2=y^2+z^2且z与y互质,

s->x 1 ,0

x+n-> t 1 , 0

x->y+n -> 1 , inf-x-y

y->x+n-> 1 ,inf-x-y

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 1000000
 7 int l,r,pd[10000005],L[200005],R[200005],cnt,sz,b[200005];
 8 int tot,go[200005],next[200005],first[200005],cost[200005],flow[200005];
 9 int op[200005],dis[200005],c[200005],vis[200005],edge[200005],from[200005];
10 int S,T,ans1,ans2;
11 int gcd(int a,int b){if (b==0) return a;else return gcd(b,a%b);}
12 int read(){
13     char ch=getchar();int t=0,f=1;
14     while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-1;ch=getchar();}
15     while (‘0‘<=ch&&ch<=‘9‘){t=t*10+ch-‘0‘;ch=getchar();}
16     return t*f;
17 }
18 void insert(int x,int y,int z,int l){
19     tot++;
20     go[tot]=y;
21     next[tot]=first[x];
22     first[x]=tot;
23     flow[tot]=z;
24     cost[tot]=l;
25 }
26 void add(int x,int y,int z,int l){
27     insert(x,y,z,l);op[tot]=tot+1;
28     insert(y,x,0,-l);op[tot]=tot-1;
29 }
30 bool spfa(){
31     for (int i=0;i<=T;i++)
32      dis[i]=inf,vis[i]=0;
33     int h=1,t=1;c[1]=S;vis[S]=1;dis[S]=0;
34     while (h<=t){
35         int now=c[h++];
36         for (int i=first[now];i;i=next[i]){
37             int pur=go[i];
38             if (dis[pur]>dis[now]+cost[i]&&flow[i]){
39                 dis[pur]=dis[now]+cost[i];
40                 edge[pur]=i;
41                 from[pur]=now;
42                 if (vis[pur]) continue;
43                 vis[pur]=1;
44                 c[++t]=pur;
45             }
46         }
47         vis[now]=0;
48     }
49     return dis[T]!=inf;
50 }
51 void updata(){
52     int mn=0x3f3f3f3f;
53     for (int i=T;i!=S;i=from[i]){
54         mn=std::min(mn,flow[edge[i]]);
55     }
56     for (int i=T;i!=S;i=from[i]){
57         ans2+=mn*cost[edge[i]];
58         flow[edge[i]]-=mn;
59         flow[op[edge[i]]]+=mn;
60     }
61     ans1+=mn;
62 }
63 int main(){
64     l=read();r=read();
65     if (l>r) std::swap(l,r);
66     for (int i=1;i<=1000;i++) pd[i*i]=i;
67     for (int j=l;j<=r;j++)
68      for (int i=j+1;i<=r;i++){
69             int k=i*i-j*j;
70             if (pd[k]&&gcd(pd[k],j)==1){
71                 b[i]=b[j]=1;
72                 cnt++;
73                 L[cnt]=j;
74                 R[cnt]=i;
75             }
76      }
77     for (int i=l;i<=r;i++)
78      if (b[i])
79       b[i]=++sz;
80     S=0;T=sz+sz+1;
81     for (int i=l;i<=r;i++)
82      if (b[i])
83       add(S,b[i],1,0),add(b[i]+sz,T,1,0);
84     for (int i=1;i<=cnt;i++){
85         add(b[L[i]],b[R[i]]+sz,1,inf-L[i]-R[i]);
86         add(b[R[i]],b[L[i]]+sz,1,inf-L[i]-R[i]);
87     }
88     while (spfa()) updata();
89     printf("%d ",ans1/2);
90     printf("%d\n",(ans1*inf-ans2)/2);
91 }
时间: 2024-08-02 15:14:17

BZOJ 2661 连连看的相关文章

BZOJ 2661 连连看(费用流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2661 题意:给出一个区间[a,b]中的全部整数,如果其中某两个数x,y(设x>y)的平方差x^2-y^2是一个完全平方数z^2,并且y与z互质,那么就可以将x和y一起消除,同时得到x+y点分数.要求就是,消除的数对尽可能多的前提下,得到的分数尽量多. 思路:首先暴力出所有合法的数对(x,y).然后将每个用到的数字拆成两个点,每个数对连一条边.最后的答案除以2即可. struct nod

bzoj 2661: [BeiJing wc2012]连连看

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define M 10000 7 #define inf 2139062143 8 using namespace std; 9 int cnt=1,n,m,T,d[M],q[2*M],f[M],head[M],next[10*M],u[10*

【BZOJ】【2661】【Beijing WC2012】连连看

网络流/费用流/二分图最大权匹配 拆点费用流求最大权匹配……妈蛋BZOJ上是数据出错了吗?为什么我拿zyf和Hzwer的代码也交不过去……害我白白WA了那么多次 1 //BZOJ 2661 2 #include<cmath> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #incl

2661: [BeiJing wc2012]连连看

Description 凡是考智商的题里面总会有这么一种消除游戏.不过现在面对的这关连连看可不是QQ游戏里那种考眼力的游戏.我们的规则是,给出一个闭区间[a,b]中的全部整数,如果其中某两个数x,y(设x>y)的平方差x2-y2是一个完全平方数z2,并且y与z互质,那么就可以将x和y连起来并且将它们一起消除,同时得到x+y点分数.那么过关的要求就是,消除的数对尽可能多的前提下,得到足够的分数.快动手动笔算一算吧. Input 只有一行,两个整数,分别表示a,b. Output 两个数,可以消去的

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445

【BZOJ】[HNOI2009]有趣的数列

[算法]Catalan数 [题解] 学了卡特兰数就会啦>_<! 因为奇偶各自递增,所以确定了奇偶各自的数字后排列唯一. 那么就是给2n个数分奇偶了,是不是有点像入栈出栈序呢. 将做偶数标为-1,做奇数标为+1,显然当偶数多于奇数时不合法,因为它压不住后面的奇数. 然后其实这种题目,打表就可知啦--QAQ 然后问题就是求1/(n+1)*C(2n,n)%p了,p不一定是素数. 参考bzoj礼物的解法. 看到网上清一色的素数筛+分解质因数解法,不解了好久,感觉写了假的礼物-- 后来觉得礼物的做法才比

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

BZOJ 1012: [JSOI2008]最大数maxnumber(线段树)

012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MB Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列