A Rational Resistance
思路:因为每个电阻的电阻是1,这就很好算了,比如要求的电阻是a/b,假设a>b,则要求电阻个数就是a/b + b/(a%b) + (a%b)/(b%(a%b))…,直到某一步的模运算那里能够整除。我也不知道为啥这样,找了俩数据,算了算是这个规律,那就这样算了。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
LL a,b;
cin >> a >> b;
if(a == b)
{
cout << 1 << endl;
return 0;
}
if(a < b) swap(a,b);
LL res = 0;
while(true)
{
res += a/b;
a %= b;
if(a == 0) break;
swap(a,b);
}
cout << res << endl;
}
B Alternating Current1
思路:只要某个地方有两个连续的+或者两个连续的-,那这里肯定可以拆开,因为这两点都是正线在上或者负线在上。那么这里就可以拆开成不重叠的,然后就相当于这俩没了,直接就把这俩左边的和右边的连接起来了。用栈判断一下就行了。如果最后栈为空,就是全拆开了,栈不为空,就拆不开。
#include <bits/stdc++.h>
using namespace std;
int main()
{
char ch;
stack<char> st;
while((ch = getchar()) != '\n')
{
if(st.size() && st.top() == ch)
st.pop();
else
st.push(ch);
}
if(st.size() == 0) puts("Yes");
else puts("No");
return 0;
}
C Read Time
思路:二分搜索,看了题解才想到,题解很详细。连二分搜索都不会写了。。
代码参考了:http://blog.csdn.net/gkhack/article/details/47612797
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5+10;
LL h[MAXN],p[MAXN];
int n,m;
bool C(LL x)
{
int cur = 0;
LL y;
for(int i = 0; i < n; ++i)
{
if(abs(h[i]-p[cur]) > x)
continue;
if(h[i] == p[cur])
++cur;
if(h[i] > p[cur])
y = max(h[i]+x-2*(h[i]-p[cur]), h[i]+(x-(h[i]-p[cur]))/2);
else
y = h[i]+x;
while(p[cur] <= y && cur < m) ++cur;
}
return cur >= m;
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; ++i)
cin >> h[i];
for(int i = 0; i < m; ++i)
cin >> p[i];
LL l = 0, r = 2e10,mid;
while(l <= r)
{
mid = (l+r) >> 1;
if(C(mid)) r = mid-1;
else l = mid+1;
}
cout << l << endl;
return 0;
}
D Water Tree
思路:dfs序+线段树,主要不好处理的地方就是操作2。先暴力处理了一发操作2,果然tle了。看题解。由题意可知,如果以点x为根节点的子树中,某一个节点是空的,那么点x也是空的,x的父节点也是空的,一直往上,他的祖先节点都是空的。所以操作1,更新的时候查询当前节点为根的子树中是否有空节点,有空节点的话,则当前子树根节点的父节点更新为空的,并且填充当前子树。操作2单点更新即可。操作3就是查询当前节点为根节点的子树中是否有空节点,有的话,当前根节点就是空的。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500100;
struct Edge
{
int to,next;
} edge[MAXN*2];
int head[MAXN],tot,cnt;
int in[MAXN],out[MAXN],fa[MAXN];
int mxor[MAXN];
int c[MAXN<<2];
int minn[MAXN<<2];
int n;
void init()
{
memset(head,-1,sizeof(head));
memset(c,-1,sizeof(c));
tot = cnt = 0;
}
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u, int f)
{
fa[u] = f;
in[u] = ++cnt;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(v == f) continue;
dfs(v,u);
}
out[u] = cnt;
}
void pushUp(int rt)
{
minn[rt] = min(minn[rt<<1], minn[rt<<1|1]);
}
void pushDown(int rt)
{
if(c[rt] != -1)
{
c[rt<<1] = c[rt<<1|1] = c[rt];
minn[rt<<1] = minn[rt<<1|1] = c[rt];
c[rt] = -1;
}
}
void update(int L, int R, int col, int l, int r, int rt)
{
if(l >= L && r <= R)
{
c[rt] = col;
minn[rt] = col;
return;
}
pushDown(rt);
int mid = (l+r) >> 1;
if(L <= mid) update(L,R,col,l,mid,rt<<1);
if(R > mid) update(L,R,col,mid+1,r,rt<<1|1);
pushUp(rt);
}
int query(int L, int R, int l, int r, int rt)
{
if(l >= L && r <= R)
return minn[rt];
pushDown(rt);
int mid = (l+r) >> 1;
int ret = 2;
if(L <= mid) ret = min(ret, query(L,R,l,mid,rt<<1));
if(R > mid) ret = min(ret, query(L,R,mid+1,r,rt<<1|1));
return ret;
}
int main()
{
init();
int u,v,q;
scanf("%d",&n);
for(int i = 0; i < n-1; ++i)
{
scanf("%d %d",&u,&v);
addedge(u,v);
addedge(v,u);
}
int op;
dfs(1,-1);
scanf("%d",&q);
while(q--)
{
scanf("%d %d",&op,&v);
if(op == 1)
{
int tmp = query(in[v],out[v],1,n,1);
update(in[v],out[v],1,1,n,1);
if(!tmp && fa[v] != -1)
update(in[fa[v]],in[fa[v]],0,1,n,1);
}
else if(op == 2) update(in[v],in[v],0,1,n,1);
else printf("%d\n",query(in[v],out[v],1,n,1));
}
return 0;
}
E Pumping Stations
不会,回头再补。