好吧…Rating在上次#141之后1756.#143只有DIv2于是就打酱油来了.最后一题Tarjan_LCA忘光光了,比赛完才写的. 前四题比较简单 Rank80
A:
水.
#include<iostream>
#include<cstdio>
using namespace std;
int n,a,b,c;
int main()
{
cin >> n;
int cnt = 0;
for (int i = 0;i<n;++i)
{
cin >> a >> b >> c;
if (a+b+c>=2)
{
++cnt;
}
}
cout << cnt << endl;
return 0;
}
B:
D = a1-a2+a3-a4....
然后Dp之.
#include<iostream>
#include<cstdio>
using namespace std;
bool vis[101][20010];
int from[101][20010];
int bj;
int n,d,l;
void dfs(int n,int cnt)
{
if (n == 0) return ;
if (n % 2 == 1)
{
dfs(n-1,cnt-from[n][cnt]);
} else
{
dfs(n-1,cnt+from[n][cnt]);
}
cout << from[n][cnt] << " ";
}
void print()
{
dfs(n,10000+d);
}
int main()
{
cin >> n >> d >> l;
vis[0][10000] = 1;
for (int i = 1;i<=n;++i)
for (int j = 0;j<=20000;++j)
if (vis[i-1][j] == 1)
{
if (i % 2 == 1) bj = 1; else bj = -1;
for (int k = 1;k<=l;++k)
{
vis[i][j+k*bj] = 1;
from[i][j+k*bj] = k;
}
}
if (vis[n][10000+d] == 0)
{
cout << "-1" << endl;
}
else print();
return 0;
}
C:
最后答案最小数一定是数组里出现的数.
排序贪心之.
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long l,tot,ansA,ansB,tmp;
long long n,k;
long long a[200000];
int main()
{
cin >> n >> k;
for (long long i = 0;i<n;++i)
{
cin >> a[i];
}
sort(a,a+n);
l = 0;
tot = 0;
ansA = 1; ansB = a[0];
tmp = 1;
for (long long i = 1;i<n;++i)
{
tot += (a[i]-a[i-1])*(i-l);
// cout << tot << endl;
++tmp;
while (tot>k && l<=i)
{
tot -= a[i]-a[l];
l++;
--tmp;
}
// cout << tot << endl;
if (tmp>ansA)
{
ansA = tmp;
ansB = a[i];
}
}
cout << ansA << " " << ansB << endl;
return 0;
}
D:
读懂题目…然后就没有然后了..
#include<iostream>
#include<cstdio>
using namespace std;
int px,py,pz;
int x,y,z;
int a1,a2,a3,a4,a5,a6;
int ans;
int main()
{
cin >> px >> py >> pz;
cin >> x >> y >> z;
cin >> a1 >> a2 >> a3 >> a4 >> a5 >> a6;
ans = 0;
if (py<0) ans += a1;
if (py>y) ans += a2;
if (pz<0) ans += a3;
if (pz>z) ans += a4;
if (px<0) ans += a5;
if (px>x) ans += a6;
cout << ans << endl;
return 0;
}
E:
感觉这次就E题比较有点意思.
题目n(10^5)个点,m(10^5)条无向边,题目保证每个点最多只能出现在一个环里面.
10^5个询问(u,v)问其间的最短路径数.
因为保证了每个点只出现在一个环里面,所以可以求点双连通,然后缩成一个点.称这种店为环点这个时候整个图就变成树形了,没有反向边,交叉边.问题又变成求LCA了,(从数据规模就可以猜到一定会是这个样子的啦).求出简单路径上得环点个数Num,2^Num即为所求.因为进入环点就可以选择绕一圈,或者不饶^_^
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
int n,m;
const int constN = 100100;
vector<int> adjacent[constN];
int color[constN];
int colorIndex = 0;
vector<int> colorToNode[constN];
void addEdge(int u,int v)
{
adjacent[u].push_back(v);
adjacent[v].push_back(u);
}
int DFN[constN];
int Low[constN];
stack<int> S;
bool inS[constN];
int index = 0;
bool visted[constN];
map<long long,int> mp;
void TarjanForGraph_Dfs(int u)
{
int v = 0;
visted[u] = 1;
Low[u] = DFN[u] = ++index;
S.push(u); inS[u] = 1;
for (int j = 0;j<adjacent[u].size();++j)
{
v = adjacent[u][j];
if (mp.count((long long)v*constN+u) > 0) continue;
mp[(long long) u * constN + v] = 1;
if (!visted[v])
{
TarjanForGraph_Dfs(v);
Low[u] = min(Low[u],Low[v]);
} else
if (inS[v])
{
Low[u] = min(Low[u],DFN[v]);
}
}
if (Low[u] == DFN[u])
{
++colorIndex;
do
{
v = S.top();
color[v] = colorIndex;
colorToNode[colorIndex].push_back(v);
S.pop();
inS[v] = 0;
} while (u !=v);
}
}
void TarjanForGraph()
{
for (int i = 1;i<=n;++i)
if (!visted[i]) TarjanForGraph_Dfs(i);
}
int DFNLca[constN];
int indexLca = 0;
int arr[constN*3];
int cnt = 0;
int Value[constN*3];
int totColor[constN];
void TarjanForLCA_Dfs(int u,int level,int colorNumber)
{
if (colorToNode[u].size()>1) ++colorNumber;
totColor[u] = colorNumber;
visted[u] = 1;
arr[++cnt] = u;
Value[cnt] = level;
DFNLca[u] = cnt;
++indexLca;
int v;
for (int i = 0;i<colorToNode[u].size();++i)
{
for (int j = 0;j<adjacent[ colorToNode[u][i] ].size();++j)
{
v = color[ adjacent[ colorToNode[u][i] ][j] ];
if (!visted[v])
{
TarjanForLCA_Dfs(v,level+1,colorNumber);
arr[++cnt] = u;
Value[cnt] = level;
}
}
}
}
int ST[constN*3][20];
int Minimum[constN*3][20];
void TarjanForLCA_ST()
{
for (int i = 1;i<=cnt;++i)
{
ST[i][0] = Value[i];
Minimum[i][0] = i;
}
for (int shift = 1;shift<20;++shift)
{
for (int i = 1;i<=cnt;++i)
{
if (i+(1<<shift)-1>cnt) break;
ST[i][shift] = min(ST[i][shift-1],ST[i+ (1<<(shift-1)) ][shift-1] );
if (ST[i][shift-1]<ST[i+ (1<<(shift-1)) ][shift-1] )
Minimum[i][shift] = Minimum[i][shift-1];
else
Minimum[i][shift] = Minimum[i+ (1<<(shift-1)) ][shift-1];
}
}
}
void TarjanForLCA()
{
for (int i = 0;i<constN;++i) visted[i] = 0;
TarjanForLCA_Dfs(1,0,0);
TarjanForLCA_ST();
}
int a,b;
const int MOD = 1000000007;
void print(int exp)
{
long long ans = 1, mul = 2;
while (exp) {
if (exp & 1) ans = (long long)(ans) * mul % MOD;
exp >>= 1;
mul = (long long)(mul) * mul % MOD;
}
cout << ans << endl;
}
int main()
{
cin >> n >> m;
for (int i = 0;i<m;++i)
{
cin >> a >> b;
addEdge(a,b);
addEdge(b,a);
}
TarjanForGraph();
TarjanForLCA();
cin >> m;
int shift = 0;
int ans = 0;
for (int i = 0;i<m;++i)
{
cin >> a >> b;
a = DFNLca[color[a]];
b = DFNLca[color[b]];
if (a>b) swap(a,b);
shift = (int) (log(b-a+1)/log(2));
int Lca = Minimum[a][shift];
if (ST[b-(1<<shift)+1][shift] < ST[a][shift])
Lca = Minimum[b-(1<<shift)+1][shift];
ans = totColor[arr[a]]+totColor[arr[b]]-2*totColor[arr[Lca]];
if (colorToNode[arr[Lca]].size()>1) ++ans;
print(ans);
}
return 0;
}

265

被折叠的 条评论
为什么被折叠?



