1、两个长度为$n$的数组$a,b$,$0 \leq a_{i} <2^{30}$。$b_{i}=-1$或者$b_{i}$为除$a_{i}$外其他数字的抑或值。现在给定$b$,如果不存在$a$,返回-1.否则输出$a$数组所有数字和的最小值。

思路:一位一位考虑。当前考虑第$k$位。对于所有不知道的数字将它们看做一个数字0或者1。现在就是一个全是01的数组$c$,那么$c_{i}$^$c_{j}$=$A_{i}$^$A_{j}$。其中$A_{i}=(a_{i}$>>$k)$&1.然后假定$A_{0}=$0或者1进行判断即可。

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <assert.h>
using namespace std;const int N=44;int n;
vector<pair<int,int> > g[N];int a[N],m;
int b[N];
int c[N];int dfs(int t)
{for(int i=0;i<(int)g[t].size();++i){int v=g[t][i].first;int w=g[t][i].second;if(b[v]==-1){b[v]=w^b[t];if(!dfs(v)) return 0;}else if(b[v]!=(w^b[t])) return 0;}return 1;
}int get()
{for(int i=0;i<m;++i) g[i].clear();for(int i=0;i<m;++i) {for(int j=i+1;j<m;++j) {g[i].push_back(make_pair(j,a[i]^a[j]));g[j].push_back(make_pair(i,a[i]^a[j]));}}int ans=m+1;for(int i=0;i<2;++i){memset(b,-1,sizeof(b));b[0]=i;if(!dfs(0)) return -1;int all=0;for(int i=0;i<m;++i) all^=b[i];int ok=1;for(int i=0;i<m&&ok;++i){if(a[i]!=(all^b[i])) ok=0;}if(!ok) continue;int tmp=0;for(int i=0;i<m;++i) tmp+=b[i];if(ans>tmp) ans=tmp;}if(ans==m+1) ans=-1;return ans;
}int cal()
{m=0;int k=0;for(int i=0;i<n;++i){if(c[i]==-1) k=1;else a[m++]=c[i];}if(k){++m;a[m-1]=0;int p0=get();a[m-1]=1;int p1=get();if(p0==-1){if(p1==-1) return -1;return p1;}else{if(p1==-1) return p0;return min(p0,p1);}}else{return get();}
}class OthersXor
{
public:long long minSum(vector<int> x){n=(int)x.size();long long sum=0;for(int i=0;i<30;++i){for(int j=0;j<n;++j){if(x[j]==-1) c[j]=-1;else c[j]=(x[j]>>i)&1;}int p=cal();if(p==-1) return -1;sum+=(1ll<<i)*p;}return sum;}
};

  

2、一个$N$个节点的有向图。给出$m$个数对$(a_{0},b_{0}),(a_{1},b_{1})...(a_{m-1},b_{m-1})$。两个节点$X,Y$有边当且仅当存在一个数对$(a_{i},b_{i})$使得$a_{i}$可整除$X$且$b_{i}$可整除$Y$。给定起点$s$终点$t$,求最短路。

思路:将数对看做节点。第$i$个节点可以向第$j$个节点连边当且仅当$lcm(b_{i},a_{j})\leq N$。

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <assert.h>
using namespace std;vector<int> g[1005];
int n;
int s,t;queue<int> Q;
int f[1005];int bfs()
{memset(f,-1,sizeof(f));f[0]=0;Q.push(0);while(!Q.empty()){int u=Q.front(); Q.pop();for(int i=0;i<(int)g[u].size();++i){int v=g[u][i];if(f[v]==-1){f[v]=f[u]+1;Q.push(v);}}}if(f[t]!=-1) return f[t]-1;return f[t];
}int gcd(int a,int b)
{return !b?a:gcd(b,a%b);
}class FromToDivisible
{
public:int shortest(int N,int S,int T,vector<int> a,vector<int> b){n=(int)a.size();s=0;t=n+1;for(int i=0;i<n;++i) for(int j=0;j<n;++j) if(i!=j){long long tmp=1ll*b[i]/gcd(b[i],a[j])*a[j];if(tmp<=N){g[i+1].push_back(j+1);}}for(int i=0;i<n;++i){if(S%a[i]==0) g[0].push_back(i+1);if(T%b[i]==0) g[i+1].push_back(t);}return bfs();}
};

  

topcoder srm 699 div1 -3相关推荐

  1. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  2. topcoder srm 691 div1 -3

    1.给定一个$n$个顶点$n$个边的图,边是$(i,a_{i})$,顶点编号$[0,n-1]$.增加一个顶点$n$,现在选出一个顶点集$M$,对于任意的在$M$中 的顶点$x$,去掉边$(x,a_{x ...

  3. topcoder srm 706 div1

    1.给定一个迷宫,点号表示不可行,井号表示可行.现在可以改变其中的一些井号的位置.问最少改变多少个井号可以使得从左上角到右下角存在路径. 思路:设高为$n$,宽为$m$,若井号的个数$S$小于$n+m ...

  4. topcoder srm 694 div1 -3

    1.给出$n$个数字,将其分成三个非空的组,每组的权值为该组所有数字的抑或.选择一种分法使得三组的权值和最大? 思路:记录前两组的权值且三组有没有数字时第三组的值.(当前两组的值知道时第三组的权值是确 ...

  5. topcoder srm 330 div1

    problem1 link 直接模拟. import java.util.*; import java.math.*; import static java.lang.Math.*;public cl ...

  6. topcoder srm 360 div1

    problem1 link (1)$n \neq m$时,假设$n<m$,那么同一行中的$m$个数字必定都相等. (2)$n=m$时,要满足任意的$i_{1},i_{2},j_{1},j_{2} ...

  7. topcoder srm 635 div1

    problem1 link 首先枚举长度$L$.然后计算每一段长度$L$的差值最大公约数,然后差值除以最大公约数的结果可以作为当前段的关键字.然后不同段就可以比较他们的关键字,一样就是可以转化的. p ...

  8. topcoder srm 495 div1

    problem1 link 从前向后确定一下,然后再从后向前确定一下.一样的话就是可以确定的. problem2 link 首先将强连通分量缩点.理论上来说,只需要遍历所有入度为0的联通块中的一个即可 ...

  9. topcoder srm 325 div1

    problem1 link $g[i]$表示解决前$i$个的代价,那么$g[i]$是所有$g[j]+cost(j+1,i)$的最小值. import java.util.*; import java. ...

  10. topcoder srm 500 div1

    problem1 link 如果decisions的大小为0,那么每一轮都是$N$个人.答案为0. 否则,如果答案不为0,那么概率最大的一定是一开始票数最多的人.因为这个人每一轮都在可以留下来的人群中 ...

最新文章

  1. [转]wxODBC(wxWidgets)中使用驱动程序方式打开数据库
  2. 防止IFRAME页被嵌套
  3. python【蓝桥杯vip练习题库】ALGO-39数组排序去重
  4. 在51aspx收集的农历日期类
  5. 翻译Raywenderlich 最新文章What’s New in Swift 4
  6. Java学习的5个阶段,助大家步步攀升
  7. C/C++混淆点-转义字符
  8. 城市交通路网(信息学奥赛一本通-T1261)
  9. 树莓派教程 - 1.2 树莓派GPIO库wiringPi 软件PWM
  10. java Calendar的学习分享
  11. 完美实现Android ListView中的TextView的跑马灯效果
  12. 华为平板鸿蒙评测,华为平板首发鸿蒙系统,Matepad Pro2 跑分首曝
  13. (二)SDRAM——SDRAM操作时序
  14. 纯CSS3画哆啦A梦
  15. mercury路由器重置后服务器无响应,路由器复位不了,重置后进不去如何解决
  16. 有哪些高含金量的编程竞赛?
  17. LPC1768 IAR环境下使用完整64K内存的方法
  18. su切换特别慢 linux,秋明 | 系统su切换用户时间非常长
  19. R语言表示文件路径应该如何使用斜杠符号?
  20. 算术表达式求值(C语言栈)

热门文章

  1. windows跳转端口
  2. CodeM2018复赛
  3. jQueru中数据交换格式XML和JSON对比
  4. 计算两个日期的时间间隔,返回的是时间间隔的日期差的绝对值.
  5. Struts+HIbernate+Spring
  6. jdbc心得-2-数据库与java相结合
  7. Maxtocode 2.0 试用版发布
  8. C# 线程thread
  9. transient、volatile关键字
  10. 时间插件--做到前几个月和后个几月的设置