250pts   PeriodicJumping

题意:从起点开始,每次按找数组jump给定的长度,即jump[0], jump[1], jump[2].....jump[n-1], 向各个方向跳,跳完后从从头开始,问最后能否达到(x,0).

限制:|x| <= (int)1e9,n <= 50, 1 <= len[i] <= (int)1e9.

分析:

题解分析的很详细,每次跳完后可达的范围离原点的距离总是一个区间[a,b],考虑下一次跳的长度r之后,可达的范围,

(1). r < a, a = a-r;

(2). a <= r <= b, a = 0;

(3). r > b , a = r-b;

而b不论r取值如何总是变为b+r.一个周期内跳跃总长度为S,那么一开始连续跳跃两个周期,看做两次跳跃长度都是S, 可达范围是[0,2S],求出在到达x之前最多跳跃多少个2S,剩下的直接模拟,直到x在所到达的范围内即可.

代码:

 #include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define esp 1e-14
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define sz(x) ((int)((x).size()))
#define pf(x) ((x)*(x))
#define pb push_back
#define pi acos(-1.0)
#define in freopen("solve_in.txt", "r", stdin);
#define bug(x) printf("Line : %u >>>>>>\n", (x));
#define TL cerr << "Time elapsed: " << (double)clock() / CLOCKS_PER_SEC * 1000 << " ms" << endl;
#define inf 0x0f0f0f0f
using namespace std;
typedef long long LL;
typedef unsigned US;
typedef pair<int, int> PII;
typedef map<PII, int> MPS;
typedef MPS::iterator IT;
vector<int> len; class PeriodicJumping {
public:
int minimalTime(int x, vector <int> jump) {
LL tmp = ;
for(int y: jump)
tmp += *y;
x = abs(x);
if(x == ) return ;
int n = jump.size();
int ans = 1LL*((x-)/tmp)*n*;
LL a = , b = (x-)/tmp*tmp; while() {
for(int y:jump) { if(a > y) {
a = a-y;
} else if(y <= b) {
a = ;
} else {
a = y-b;
}
b+=y;
ans++;
if(x >= a && x <= b)
break;
}
if(x >= a && x <= b)
break;
}
return ans;
}
};

500pts DoubleTree

题意: 两棵树,共n个结点,对应编号的结点权值相同,可正可负,求从中选出一个结点结合,使得选出的集合在两棵树上都是一棵子树,即都联通,权值要求最大.

限制:2 <= n <= 50, |权值 | <= 1000.

分析:

选出任意个结点构成一棵子树的条件时,这些结点间相互可达,也就是都能到达同一个结点,因为树中路径唯一,不妨把这个点当做根结点。

依次考虑每个结点做根时,考虑剩下的结点选中时的情形,两棵树中这个结点到根路径上所有结点都要选中,这样又会引入一些选中的结点,总结起来就是,所有选中的结点在两棵树中到根的路径上其他结点都要选中。

具体建图时,分别对两棵树dfs,每个节点到其父节点连边,当要选中这个结点时,必须从这个结点出发,将所有能达的点全部选中,同时使得权值和最大,问题就转化为最大权闭合图了。这个可以参考胡伯涛的论文。

代码:

 #include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define esp 1e-14
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define sz(x) ((int)((x).size()))
#define pf(x) ((x)*(x))
#define pb push_back
#define pi acos(-1.0)
#define in freopen("solve_in.txt", "r", stdin);
#define bug(x) printf("Line : %u >>>>>>\n", (x));
#define TL cerr << "Time elapsed: " << (double)clock() / CLOCKS_PER_SEC * 1000 << " ms" << endl;
#define inf 0x0f0f0f0f
using namespace std;
typedef long long LL;
typedef unsigned US;
typedef pair<int, int> PII;
typedef map<PII, int> MPS;
typedef MPS::iterator IT;
const int maxn = ; int src, sink; struct Edge {
int u, v, c;
Edge() {}
Edge(int u, int v, int c):u(u), v(v), c(c) {}
}; struct MaxFlow {
int n, m;
vector<int> G[maxn];
vector<Edge> edges;
int Now[maxn], Dfn[maxn]; void init(int n) {
this->n = n;
for(int i = ; i < n; i++)
G[i].clear();
edges.clear();
}
void add(int u, int v, int c) {
// cout << u << ' ' << v << endl;
edges.pb(Edge(u, v, c));
edges.pb(Edge(v, u, ));
m = edges.size();
G[u].pb(m-);
G[v].pb(m-);
}
int ISAP(int s, int flow) {
if(s == sink) return flow;
int now = , vary, tab = n, v;
for(int i = ; i < (int)G[s].size(); i++) {
Edge &e = edges[G[s][i]];
if(e.c > ) {
if(Dfn[s] == Dfn[v = e.v] + )
vary = ISAP(v, min(flow-now, e.c)), now += vary,
e.c -= vary, edges[G[s][i]^].c += vary;
if(Dfn[src] == n) return now;
if(e.c > ) tab = min(tab, Dfn[v]);
if(flow == now) break;
}
}
if(now == ) {
if(--Now[Dfn[s]] == )
Dfn[src] = n;
Now[Dfn[s] = tab+]++;
} return now;
}
int getAns() {
memset(Now, , sizeof Now);
memset(Dfn, , sizeof Dfn);
Now[] = n;
int ans = ;
while(Dfn[src] < n)
ans += ISAP(src, inf);
return ans;
}
} solver; class DoubleTree {
public:
int n;
int g[maxn][maxn];
vector<int> tree[][maxn];
int rt;
void add(int id, int u, int v) { tree[id][u].pb(v);
tree[id][v].pb(u);
}
void dfs(int id, int u, int fa) {
if(fa != - && fa != rt) {
g[u][fa] = ;
}
for(int i = ; i < sz(tree[id][u]); i++) {
int v = tree[id][u][i];
if(v == fa) continue;
dfs(id, v, u);
}
}
int maximalScore(vector <int> a, vector <int> b, vector <int> c, vector <int> d, vector <int> s) {
n = sz(a)+;
int mx, z; for(int i = ; i < n-; i++) {
add(, a[i], b[i]);
add(, c[i], d[i]);
}
int ans = ;
src = n, sink = n+; for(int i = ; i < n; i++ ){
mx = z = ;
memset(g, , sizeof g); for(int j = ; j < n; j++) {
mx += (i != j ? abs(s[j]) : );
z += (i != j && s[j] > ? s[j] : );
}
mx+=;
rt = i;
dfs(, i, -);
dfs(, i, -);
//for(int ii = 0; ii < n; ii++, puts("")) for(int j = 0; j < n; j++)
// cout << g[ii][j] << ' ';
solver.init(n+);
for(int u = ; u < n; u++) {
if(u != rt) {
if(s[u] > ) solver.add(src, u, s[u]);
else solver.add(u, sink, -s[u]);
}
for(int v = ; v < n; v++) {
if(!g[u][v]) continue;
solver.add(u, v, mx);
}
} ans = max(ans, z-solver.getAns()+s[i]);
}
return ans;
}
};
int main(){
return ;
} // Powered by FileEdit

1000pts GCDLCM 

题意:现有n个正整数,给出4个数组,描述x[A[i]],x[B[i]],的LCM或GCD为C[i],问能否找到这样一组正整数。

n <= 200, m <= 200.

分析:GCD要求A[i],B[i]的相应质因子p的个数最小值 = m(m为C[i]包含的质因子p的个数), 即min(A[i], B[i]) = m。即A[i] = m && B[i] >= m 或 B[i] = m && A[i] >= m.LCM则是将min改为max.

这样对C[]分解质因数后,单独考虑其中每个质因子的问题,对A[i], B[i], C[i]分析可得到一系列条件, 将A[i] = m && B[i] >= m , B[i] = m && A[i] >= m 分别看成X,Y表达式,原来的GCD[i]或LCM[i]问题变成了,X[i]或Y[i]的表达式,注意对于每个i,X[i]和Y[i]中至少有一个成立,当然可以有两个同时成立,然后便是X[i],Y[i],X[j],Y[j]中必然会存在矛盾,处理一下,最后用2-sat解决.

代码:

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define esp 1e-14
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define sz(x) ((int)((x).size()))
#define pf(x) ((x)*(x))
#define pb push_back
#define pi acos(-1.0)
#define in freopen("solve_in.txt", "r", stdin);
#define bug(x) printf("Line : %u >>>>>>\n", (x));
#define TL cerr << "Time elapsed: " << (double)clock() / CLOCKS_PER_SEC * 1000 << " ms" << endl;
#define inf 0x0f0f0f0f
using namespace std;
typedef long long LL;
typedef unsigned US;
typedef pair<int, int> PII;
typedef map<PII, int> MPS;
typedef MPS::iterator IT; const int maxn = + ;
//2-sat
struct twoSat {
int n;
int mark[maxn], S[maxn];
vector<list<int> > g;
int c;
void init(int n) {
this->n = n;
g.resize(n*);
for(auto &x:g)
x.clear();
memset(mark, , sizeof mark);
}
void add(int x, int y) {
g[x].pb(y);
}
bool dfs(int x) {
if(mark[x^]) return false;
if(mark[x]) return true;
S[c++] = x;
mark[x] = ;
for(int y: g[x]) {
if(!dfs(y)) return false;
}
return true;
}
bool solve() {
for(int i = ; i < n*; i += ) {
if(!mark[i] && !mark[i+]) {
c = ;
if(!dfs(i)) {
while(c) mark[S[--c]] = ;
if(!dfs(i+)) return false;
}
}
}
return true;
}
} solver;
struct State {
int a, b, c, d;
State() {}
State(int a, int b, int c, int d):a(a), b(b), c(c), d(d) {}
};
vector<State> sta; class GCDLCM {
public:
set<int> div;//relevant primes
vector<PII> factor[ + ];
//get prime factor of n, store in vec
void getPrimeFac(int n) {
for(int i = ; i <= n/i; i++) { if(n%i == ) {
while(n%i == ) {
n /= i;
}
div.insert(i);
}
}
if(n != ) {
div.insert(n);
}
}
bool contradiction(int x, int y) {
int a0 = sta[x].a, b0 = sta[x].b, c0 = sta[x].c, d0 = sta[x].d;
int a1 = sta[y].a, b1 = sta[y].b, c1 = sta[y].c, d1 = sta[y].d;
if(a0 == a1 && c0 != c1) {
return true;
}
if(a0 == b1 && ((d1 && c0 < c1) || (!d1 && c0 > c1))) {
return true;
}
if(b0 == a1 && ((d0 && c1 < c0) || (!d0 && c1 > c0))) {
return true;
}
if(b0 == b1 && ((d0 > d1 && c0 > c1) || (d0 < d1 && c0 < c1))) {
return true;
}
return false;
}
string possible(int n, string type, vector <int> A, vector <int> B, vector <int> C) {
int m = sz(A);
for(int i = ; i < m; i++)
getPrimeFac(C[i]);
for(int u: div) {
sta.clear();
for(int j = ; j < m; j++) {
int r = ;
int y = C[j];
while(y%u == ) {
r++;
y /= u;
}
sta.pb(State(A[j], B[j], r, type[j] == 'G'));
sta.pb(State(B[j], A[j], r, type[j] == 'G'));
} solver.init(sz(sta));
//add edge x->~y, ~y->x,etc.
for(int i = ; i < sz(sta); i += ) {
//solver.add(i<<1, (i+1)<<1|1);
solver.add((i+)<<|, i<<);
//solver.add((i+1)<<1, i<<1|1);
solver.add(i<<|, (i+)<<);
}
for(int i = ; i < sz(sta); i++) for(int j = ; j < sz(sta); j++) {
if(contradiction(i, j)) {
solver.add(i<<, j<<|);
solver.add(j<<, i<<|);
}
}
if(!solver.solve()) return "Solution does not exist";
}
return "Solution exists";
}
};

学习了一下list,和vector最大区别便是不支持随机存取,可以看做是STL中的双向链表,支持首尾插入,删除。

TopCoder SRM 633div1的更多相关文章

  1. TopCoder SRM 560 Div 1 - Problem 1000 BoundedOptimization & Codeforces 839 E

    传送门:https://284914869.github.io/AEoj/560.html 题目简述: 定义"项"为两个不同变量相乘. 求一个由多个不同"项"相 ...

  2. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  3. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  4. TopCoder SRM 667 Div.2题解

    概览: T1 枚举 T2 状压DP T3 DP TopCoder SRM 667 Div.2 T1 解题思路 由于数据范围很小,所以直接枚举所有点,判断是否可行.时间复杂度O(δX × δY),空间复 ...

  5. Topcoder Srm 673 Div2 1000 BearPermutations2

    \(>Topcoder \space Srm \space 673 \space Div2 \space 1000 \space BearPermutations2<\) 题目大意 : 对 ...

  6. Topcoder Srm 671 Div2 1000 BearDestroysDiv2

    \(>Topcoder \space Srm \space 671 \space Div2 \space 1000 \space BearDestroysDiv2<\) 题目大意 : 有一 ...

  7. [topcoder]SRM 646 DIV 2

    第一题:K等于1或者2,非常简单.略.K更多的情况,http://www.cnblogs.com/lautsie/p/4242975.html,值得思考. 第二题:http://www.cnblogs ...

  8. [topcoder]SRM 633 DIV 2

    第一题,http://community.topcoder.com/stat?c=problem_statement&pm=13462&rd=16076 模拟就可以了. #includ ...

  9. TopCoder<SRM>上的一道1100分的题目解析附代码

    首先我们来简单看一下这道题的statement Problem Statement      Note that in the following problem statement, all quo ...

随机推荐

  1. Ubuntu搜狗输入法的使用

    下载搜狗拼音输入法安装包 删除ibus,确认没有以ibus开头的包存在 sudo dpkg -P ibus ibus-gtk ibus-gtk3 ibus-pinyin ibus-pinyin-db- ...

  2. jquery循环table中tbody的tr中input:text,将值进行拼接传入控制器并返回状态和描述

    引用jquery $(function(){ $("#按钮id").click(function(){ var nums="";//变量 $("#ta ...

  3. 【转】MyEclipse快捷键大全(绝对全)

    ref:http://www.douban.com/note/254195820/?type=like# ctrl+w 关闭单个窗口 F3 跳转到类.变量的声明 F11 运行上次程序 Ctrl + F ...

  4. dmp文件导入

    dmp文件导入 1,打开“开始”-->输入cmd—> sqlplus log: 2,输入 conn / as sysdba管理员账户登录: 3,需要创建表空间,如果我们知道需要导入的数据库 ...

  5. js各类共用方法

    function GetParameterValueByName(parametername) { var reg = new RegExp("(^|&)" + param ...

  6. 【转载】Powershell在世纪互联Office365中批量将用户添加到组

    $NewUserPath = ".\Office365AddUserToGroup.csv" $NewUsers = import-csv $NewUserPath foreach ...

  7. linux常用命令收集(持续中)

    mv  :  既可以重命名,又可以移动文件或文件夹 例子:将目录A重命名为B mv A B 例子:将/a目录移动到/b下,并重命名为c mv /a /b/c 其实在文本模式中要重命名文件或目录的话也是 ...

  8. 第一次比赛的 C题 (好后面才补的....) CodeForces 546B

    Description Colonel has n badges. He wants to give one badge to every of his n soldiers. Each badge ...

  9. ASP.NET对HTML元素进行权限控制(一)

    一个HTML页面有很多的元素比如<DIV>,<P>等.这些元素构成了HTML页面.在Web开发中权限控制是每个系统都要用到了.界面每个元素的权限也是需要控制的.比如一个查询用户 ...

  10. substr,mb_substr,iconv_substr,array_slice

    通过一个例子来看其关系 /** +---------------------------------------------------------- * 字符串截取,支持中文和其他编码 +----- ...