学长写的

F. Fantastic Graph

"Oh, There is a bipartite graph.""Make it Fantastic."

X wants to check whether a bipartite graph is a fantastic graph. He has two fantastic numbers, and he wants to let all the degrees to between the two boundaries. You can pick up several edges from the current graph and try to make the degrees of every point to between the two boundaries. If you pick one edge, the degrees of two end points will both increase by one. Can you help X to check whether it is possible to fix the graph?

Input

There are at most 3030 test cases.

For each test case,The first line contains three integers NN the number of left part graph vertices, MM the number of right part graph vertices, and KK the number of edges ( 1 \le N \le 20001≤N≤2000,0 \le M \le 20000≤M≤2000,0 \le K \le 60000≤K≤6000 ). Vertices are numbered from 11 to NN.

The second line contains two numbers L, RL,R (0 \le L \le R \le 300)(0≤L≤R≤300). The two fantastic numbers.

Then KK lines follows, each line containing two numbers UU, VV (1 \le U \le N,1 \le V \le M)(1≤U≤N,1≤V≤M). It shows that there is a directed edge from UU-th spot to VV-th spot.

Note. There may be multiple edges between two vertices.

Output

One line containing a sentence. Begin with the case number. If it is possible to pick some edges to make the graph fantastic, output "Yes" (without quote), else output "No" (without quote).



  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. #define INF 0x3f3f3f3f
  4. #define inf 0x3f3f3f3f
  5. #define fi first
  6. #define se second
  7. using namespace std;
  8. const int maxn = 6e3+32;
  9. int n,m,k;
  10. int du[2000+42];
  11. int du2[2000+32];
  12. int L,R;
  13. const int MX = 4000+54;
  14. const int MXE = 19000+43;
  15. struct MaxFlow
  16. {
  17. struct Edge
  18. {
  19. int v, w, nxt;
  20. } edge[MXE],edge2[MXE];
  21. int tot, num, s, t;
  22. int head[MX];
  23. void init()
  24. {
  25. memset(head, -1, sizeof(head));
  26. tot = 0;
  27. }
  28. void add(int u, int v, int w)
  29. {
  30. edge[tot].v = v;
  31. edge[tot].w = w;
  32. edge[tot].nxt = head[u];
  33. head[u] = tot++;
  34. edge[tot].v = u;
  35. edge[tot].w = 0;
  36. edge[tot].nxt = head[v];
  37. head[v] = tot++;
  38. }
  39. int d[MX], vis[MX], gap[MX];
  40. void bfs()
  41. {
  42. memset(d, 0, sizeof(d));
  43. memset(gap, 0, sizeof(gap));
  44. memset(vis, 0, sizeof(vis));
  45. queue<int>q;
  46. q.push(t);
  47. vis[t] = 1;
  48. while (!q.empty())
  49. {
  50. int u = q.front();
  51. q.pop();
  52. for (int i = head[u]; ~i; i = edge[i].nxt)
  53. {
  54. int v = edge[i].v;
  55. if (!vis[v])
  56. {
  57. d[v] = d[u] + 1;
  58. gap[d[v]]++;
  59. q.push(v);
  60. vis[v] = 1;
  61. }
  62. }
  63. }
  64. }
  65. int last[MX];
  66. int dfs(int u, int f)
  67. {
  68. if (u == t) return f;
  69. int sap = 0;
  70. for (int i = last[u]; ~i; i = edge[i].nxt)
  71. {
  72. int v = edge[i].v;
  73. if (edge[i].w > 0 && d[u] == d[v] + 1)
  74. {
  75. last[u] = i;
  76. int tmp = dfs(v, min(f - sap, edge[i].w));
  77. edge[i].w -= tmp;
  78. edge[i ^ 1].w += tmp;
  79. sap += tmp;
  80. if (sap == f) return sap;
  81. }
  82. }
  83. if (d[s] >= num) return sap;
  84. if (!(--gap[d[u]])) d[s] = num;
  85. ++gap[++d[u]];
  86. last[u] = head[u];
  87. return sap;
  88. }
  89. int solve(int st, int ed, int n)
  90. {
  91. int flow = 0;
  92. num = n;
  93. s = st;
  94. t = ed;
  95. bfs();
  96. memcpy(last, head, sizeof(head));
  97. while (d[s] < num) flow += dfs(s, inf);
  98. return flow;
  99. }
  100. } F;
  101. int S,T;
  102. void update(int u,int v,int L,int R)
  103. {
  104. F.add(u,v,R-L);
  105. F.add(S, v, L);
  106. F.add(u, T, L);
  107. }
  108. pair<int,int>Q[6000+53];
  109. int main()
  110. {
  111. int ka = 1;
  112. while(~scanf("%d%d%d",&n,&m,&k))
  113. {
  114. F.init();
  115. S = n+m+2;
  116. T = n+m+3;
  117. F.add(n+m+1, 0, INF);
  118. for(int i = 0;i<=max(n,m);i++){
  119. du[i] = du2[i] = 0;
  120. }
  121. scanf("%d%d",&L,&R);
  122. for(int i = 1;i<=n;i++){
  123. update(0,i,L,R);
  124. }
  125. for(int i = n+1;i<=n+m;i++)
  126. {
  127. update(i,n+m+1,L,R);
  128. }
  129. for(int i = 0;i<k;i++){
  130. int u,v;
  131. scanf("%d%d",&u,&v);
  132. Q[i].first = u;
  133. Q[i].second = v;
  134. du[u]++;
  135. du2[v]++;
  136. F.add(u, v+n, 1);
  137. }
  138. printf("Case %d: ",ka++);
  139. int ret = F.solve(S, T, T + 11);
  140. if(ret != (n+m)*L) puts("No");
  141. else puts("Yes");
  142. }
  143. }

B. Call of Accepted

You and your friends are at the table, playing an old and interesting game - the Call of Cthulhu.

There is a mechanism in the game: rolling the dice. You use a notation to communicate the type of dice that needs to be rolled - the operator "\mathop{\rm d}d". "x\mathop{\rm d}yxdy" means that an yy-sided dice should be rolled xx times and the sum of the results is taken.

Formally, for any two integers x, yx,y satisfying x \geq 0x≥0 and y \geq 1y≥1 , "x\mathop{\rm d}yxdy" means the sum of xx random integers in the range of [1, y][1,y]. It's obvious that either x < 0x<0 or y < 1y<1 makes the expression x\ {\rm d}\ yx d y illegal. For example: "2\mathop{\rm d}62d6" means that rolling a 66-sided dice 22 times. At this time, the result can be at least [1, 1] = 2[1,1]=2, and at most [6, 6] = 12[6,6]=12. The results of rolling can be used extensively in many aspects of the game. For example, an "1\mathop{\rm d}1001d100" can be used to determine whether an action with a percentage probability is successful, and a "3\mathop{\rm d}6+33d6+3 * 22" can be used to calculate the total damage when being attacked by 33 monsters simultaneously. In particular, the precedence of "\mathop{\rm d}d" is above "*". Since the operator "\mathop{\rm d}d" does not satisfy the associative law, it's necessary to make sure that "\mathop{\rm d}d" is right-associative.

Now the game has reached its most exciting stage. You are facing the Great Old One - Cthulhu. Because the spirit has been greatly affected, your sanity value needs to be deducted according to the result of rolling. If the sanity value loses too much, you will fall into madness. As a player, you want to write a program for knowing the minimum and maximum loss of sanity value before rolling, in order to make a psychological preparation.

The oldest and strongest emotion of mankind is fear, and the oldest and strongest kind of fear is fear of the unknown. ----H. P. Lovecraft

Input

There are multiple sets of input, at most 3030 cases.

Each set of input contains a string of only '+', '-', '*', 'd', '(', ')' and integers without spaces, indicating the expression of this sanity loss. The length of the expression will be at most 100100.

It is guaranteed that all expressions are legal, all operators except for '(' and ')' are binary, and all intermediate results while calculating are integers in the range of [-2147483648, 2147483647][−2147483648,2147483647].

The most merciful thing in the world, I think, is the inability of the human mind to correlate all its contents. We live on a placid island of ignorance in the midst of black seas of infinity, and it was not meant that we should voyage far. ----H. P. Lovecraft

Output

For each set of data, output a line of two integers separated by spaces, indicating the minimum and maximum possible values of the sanity loss.



  1. #include<bits/stdc++.h>
  2. #define lson l,m,rt<<1
  3. #define rson m+1,r,rt<<1|1
  4. #define x first
  5. #define y second
  6. #define rep(i,a,b) for(int i=a;i<(b);++i)
  7. #define per(i,a,b) for(int i=a-1;i>=(b);--i)
  8. #define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
  9. #define sub(x,y) x=((x)-(y)<0)?(x)-(y)+mod:(x)-(y)
  10. #define clr(a,b) memset(a,b,sizeof(a))
  11. #define eps 1e-10
  12. using namespace std;
  13. typedef long long ll;
  14. typedef unsigned long long ull;
  15. typedef vector<int> VI;
  16. typedef pair<int, int> PII;
  17. typedef unsigned int ui;
  18. const int INF = 0x3f3f3f3f;
  19. const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
  20. const int mod = 1e9 + 7;
  21. const int MX = 2e6 + 5;
  22. vector<string>pre, s;
  23. string str;
  24. bool isoperator(string op) {
  25. if(op == "+" || op == "-" || op == "*" || op == "d") return 1;
  26. return 0;
  27. }
  28. int priority(string op) {
  29. if(op == "#") return -1;
  30. if(op == "(") return 0;
  31. if(op == "+" || op == "-") return 1;
  32. if(op == "*") return 2;
  33. if(op == "d") return 3;
  34. return -1;
  35. }
  36. void postfix() {
  37. stack<string> OPTR; //运算符栈
  38. stack<string> OPND; //数据栈
  39. OPTR.push("#");
  40. rep(i, 0, pre.size()) {
  41. if (pre[i] == "(") OPTR.push(pre[i]);
  42. else if(pre[i] == ")") {
  43. while(OPTR.top() != "(") {
  44. OPND.push(OPTR.top());
  45. OPTR.pop();
  46. }
  47. OPTR.pop();
  48. } else if (isoperator(pre[i])) {
  49. while(!OPTR.empty() && (priority(pre[i]) < priority(OPTR.top()) || priority(pre[i]) == priority(OPTR.top()) && pre[i] != "d")) {
  50. OPND.push(OPTR.top());
  51. OPTR.pop();
  52. }
  53. OPTR.push(pre[i]);
  54. } else OPND.push(pre[i]);
  55. }
  56. while(OPTR.top() != "#") {
  57. OPND.push(OPTR.top());
  58. OPTR.pop();
  59. }
  60. OPTR.pop();
  61. //利用操作符栈逆序即可得到后缀表达式
  62. while(!OPND.empty()) {
  63. OPTR.push(OPND.top());
  64. OPND.pop();
  65. }
  66. s.clear();
  67. while(!OPTR.empty()) {
  68. s.push_back(OPTR.top());
  69. OPTR.pop();
  70. }
  71. }
  72. bool is_dig(char ch) {return ch >= '0' && ch <= '9';}
  73. void pre_solve() {
  74. pre.clear();
  75. rep(i, 0, str.length()) {
  76. if(is_dig(str[i])) {
  77. rep(j, i, str.length()) {
  78. if(!is_dig(str[j])) {
  79. pre.push_back(str.substr(i, j - i));
  80. i = j - 1;
  81. break;
  82. }
  83. if(j == str.length() - 1) {
  84. pre.push_back(str.substr(i, j - i + 1));
  85. i = j;
  86. break;
  87. }
  88. }
  89. } else pre.push_back(str.substr(i, 1));
  90. }
  91. }
  92. ll str_to_int(string st) {
  93. ll ret = 0;
  94. rep(i, 0, st.length()) ret = ret * 10 + st[i] - '0';
  95. return ret;
  96. }
  97. struct node {
  98. ll l, r;
  99. node(ll l = 0, ll r = 0): l(l), r(r) {}
  100. node(string st) {l = r = str_to_int(st);}
  101. node operator-(const node& _A)const {
  102. return node(l - _A.r, r - _A.l);
  103. }
  104. node operator+(const node& _A)const {
  105. return node(l + _A.l, r + _A.r);
  106. }
  107. node operator*(const node& _A)const {
  108. node ret;
  109. ll a = l * _A.l;
  110. ll b = l * _A.r;
  111. ll c = r * _A.l;
  112. ll d = r * _A.r;
  113. ret.l = min(min(a, b), min(c, d));
  114. ret.r = max(max(a, b), max(c, d));
  115. return ret;
  116. }
  117. node operator/(const node& _A)const {
  118. node ret;
  119. ll l1 = max(l, 0ll), r1 = r;
  120. ret.l = l1, ret.r = r1 * _A.r;
  121. return ret;
  122. }
  123. };
  124. int main() {
  125. #ifdef local
  126. freopen("in.txt", "r", stdin);
  127. #endif // local
  128. while(cin >> str) {
  129. pre_solve();
  130. postfix();
  131. stack<node>stk;
  132. node a, b;
  133. rep(i, 0, s.size()) if(isoperator(s[i])) {
  134. b = stk.top(); stk.pop();
  135. a = stk.top(); stk.pop();
  136. // printf("[%lld %lld]\n", a.l, a.r);
  137. // printf("[%lld %lld]\n", b.l, b.r);
  138. if(s[i] == "-") a = a - b;
  139. if(s[i] == "+") a = a + b;
  140. if(s[i] == "*") a = a * b;
  141. if(s[i] == "d") a = a / b;
  142. stk.push(a);
  143. } else stk.push(node(s[i]));
  144. a = stk.top();
  145. printf("%lld %lld\n", a.l, a.r);
  146. }
  147. return 0;
  148. }

G.Spare time



\(a_{n} = a_{n-1}+2\times n\)

\(a_{n} = (a_{n}-a_{n-1})+(a_{n-1}-a_{n-2})+...+(a_{2}-a_{1})+a_{1} = n\times (n+1)\)

\(S_{n} = \sum_{i=1}^n i\times(i+1) = n\times(n+1)/2 + n\times(n+1)\times(2n+1)/6\)

 利用容斥思想,如当\(m=6\)时,有\(2\),\(3\)两个质因子。既然要求与\(m\)互素的下标的数之和,我们枚举素因子的倍数,二进制枚举最简的倍数。

 当枚举到\(2\)时,要删去\(2(2*1),4(2*2),6(2*3)\);当枚举到\(3\)时,要删去\(3(3*1),6(3*2)\);(注意到\(6\)被删了两次);当枚举到\(6\)时,要加上\(6\)哦。

容斥:

令\(tmp = tot*get\_num1(cnt)+tot*tot*get\_num2(cnt);\)

  1. tmp = tot*get_num1(cnt)+tot*tot*get_num2(cnt);

若tot是偶数个质因子的倍数,答案加上这个数及其倍数的贡献,即tmp。

若tot是奇数个质因子的倍数,答案减去这个数及其倍数的贡献,即tmp。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const LL MOD = (LL)1e9 + 7;
  5. LL n, m, inv2, inv6;
  6. vector<int> ve;
  7. LL inv(LL t){
  8. return t == 1LL? 1LL: (MOD-MOD/t)*inv(MOD%t)%MOD;
  9. }
  10. LL get_num1(LL n){
  11. return n*(n+1)%MOD*inv2%MOD;
  12. }
  13. LL get_num2(LL n){
  14. return n*(n+1)%MOD*(2*n%MOD+1)%MOD*inv6%MOD;
  15. }
  16. int main(){
  17. inv2 = inv(2), inv6 = inv(6);
  18. while(~scanf("%lld%lld", &n, &m)){
  19. ve.clear();
  20. int tm = m;
  21. for(int i = 2; (LL)i * i <= m && i <= n; ++i){
  22. if(tm % i == 0){
  23. ve.push_back(i);
  24. while(tm % i == 0)tm /= i;
  25. }
  26. if(tm == 1)break;
  27. }
  28. if(tm != 1)ve.push_back(tm);
  29. int len = ve.size(), state = 1 << len;
  30. LL ans = (get_num1(n)+get_num2(n))%MOD;
  31. ans = 0;
  32. for(int i = 0; i < state; ++i){
  33. LL tot = 1, cnt;
  34. int num = 0;
  35. for(int j = 0; j < len; ++j){
  36. if(i&(1<<j)){
  37. ++num;
  38. tot *= ve[j];
  39. }
  40. }
  41. cnt = n/tot;
  42. //printf("*%lld %lld %d\n", tot,cnt,num);
  43. if(num % 2 == 0){
  44. ans = (ans+ tot*tot%MOD*get_num2(cnt)%MOD+tot*get_num1(cnt)%MOD)%MOD;
  45. }else{
  46. ans = (ans- tot*tot%MOD*get_num2(cnt)%MOD-tot*get_num1(cnt)%MOD)%MOD;
  47. ans = (ans + MOD)%MOD;
  48. }
  49. }
  50. printf("%lld\n", ans);
  51. }
  52. return 0;
  53. }

#### HDU6397容斥

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <queue>
  5. #include <map>
  6. using namespace std;
  7. typedef long long LL;
  8. const int MXN = 3e5 + 6;
  9. const int MXT = 1e5 + 5;
  10. const int mod = 998244353;
  11. LL n, m, k;
  12. LL f[MXN], invF[MXN];
  13. LL niyuan(int t) {
  14. return t == 1? 1: (mod-mod/t)*niyuan(mod%t)%mod;
  15. }
  16. LL ksm(LL a, int b) {
  17. LL ans = 1;
  18. while(b) {
  19. if(b&1) ans = ans * a %mod;
  20. b >>= 1;
  21. a = a * a %mod;
  22. }
  23. return ans;
  24. }
  25. void init() {
  26. f[0] = 1; invF[0] = 1;
  27. for(int i = 1; i < MXN; ++i) f[i] = f[i-1] * i % mod;
  28. //invF[MXN-1] = niyuan(f[MXN-1]);
  29. invF[MXN-1] = ksm(f[MXN-1], mod-2);
  30. for(int i = MXN-2; i >= 1; --i) invF[i] = invF[i+1]*(i+1)%mod;
  31. }
  32. LL COMB(LL n, LL m) {
  33. if(n < m) return 0;
  34. return f[n] * invF[m] % mod * invF[n-m] % mod;
  35. }
  36. int main(int argc, char const *argv[]) {
  37. #ifndef ONLINE_JUDGE
  38. //freopen("E://ADpan//in.in", "r", stdin);
  39. #endif
  40. init();
  41. int tim;
  42. scanf("%d", &tim);
  43. while(tim--) {
  44. scanf("%lld%lld%lld", &n, &m, &k);
  45. LL ans = COMB(k+m-1,m-1), tmp;
  46. for(int i = 1; i <= m; ++i) {
  47. tmp = COMB(k+m-i*n-1, m-1) * COMB(m, i) % mod;
  48. if(i & 1) ans = (ans - tmp + mod)%mod;
  49. else ans = (ans + tmp)%mod;
  50. }
  51. printf("%lld\n", ans);
  52. }
  53. return 0;
  54. }
  55. /*
  56. 字母xi=[0,n-1],问有多少个长度为m的单词,其和为k
  57. */

ACM-ICPC 2018 沈阳赛区网络预赛-B,F,G的更多相关文章

  1. ACM-ICPC 2018 沈阳赛区网络预赛 K Supreme Number(规律)

    https://nanti.jisuanke.com/t/31452 题意 给出一个n (2 ≤ N ≤ 10100 ),找到最接近且小于n的一个数,这个数需要满足每位上的数字构成的集合的每个非空子集 ...

  2. ACM-ICPC 2018 沈阳赛区网络预赛-K:Supreme Number

    Supreme Number A prime number (or a prime) is a natural number greater than 11 that cannot be formed ...

  3. ACM-ICPC 2018 沈阳赛区网络预赛-D:Made In Heaven(K短路+A*模板)

    Made In Heaven One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with her. ...

  4. 图上两点之间的第k最短路径的长度 ACM-ICPC 2018 沈阳赛区网络预赛 D. Made In Heaven

    131072K   One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with her. Howe ...

  5. ACM-ICPC 2018 沈阳赛区网络预赛 J树分块

    J. Ka Chang Given a rooted tree ( the root is node 11 ) of NN nodes. Initially, each node has zero p ...

  6. ACM-ICPC 2018 沈阳赛区网络预赛 K. Supreme Number

    A prime number (or a prime) is a natural number greater than 11 that cannot be formed by multiplying ...

  7. ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph

    "Oh, There is a bipartite graph.""Make it Fantastic." X wants to check whether a ...

  8. Fantastic Graph 2018 沈阳赛区网络预赛 F题

    题意: 二分图 有k条边,我们去选择其中的几条 每选中一条那么此条边的u 和 v的度数就+1,最后使得所有点的度数都在[l, r]这个区间内 , 这就相当于 边流入1,流出1,最后使流量平衡 解析: ...

  9. ACM-ICPC 2018 沈阳赛区网络预赛 F Fantastic Graph(贪心或有源汇上下界网络流)

    https://nanti.jisuanke.com/t/31447 题意 一个二分图,左边N个点,右边M个点,中间K条边,问你是否可以删掉边使得所有点的度数在[L,R]之间 分析 最大流不太会.. ...

  10. ACM-ICPC 2018 沈阳赛区网络预赛 B Call of Accepted(表达式求值)

    https://nanti.jisuanke.com/t/31443 题意 给出一个表达式,求最小值和最大值. 表达式中的运算符只有'+'.'-'.'*'.'d',xdy 表示一个 y 面的骰子 ro ...

随机推荐

  1. Delphi 鼠标控制函数GetCursorPos、SetCursorPos

    GetCursorPos函数  获取鼠标的位置 var P: TPoint; begin GetCursorPos(P); //获取鼠标位置 end; SetCursorPos函数 设置鼠标的位置 v ...

  2. Tyvj 1518 CPU监控(线段树)

    题目描述: Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用 ...

  3. input限制字符长度 - composition

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. AcWing 139. 回文子串的最大长度 hash打卡

    如果一个字符串正着读和倒着读是一样的,则称它是回文的. 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少. 输入格式 输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个 ...

  5. Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

    环境搭建 怎么设置Mysql支持外联? use mysql; grant all privileges on *.* to root@'%' identified by '密码'; //授权语句 fl ...

  6. 炼数成金数据分析课程---10、python中如何画图

    炼数成金数据分析课程---10.python中如何画图 一.总结 一句话总结: 主要matplotlib库,pandas中也可以画一些基础图 大纲+实例快速学习法 1.matplotlib的最简单画图 ...

  7. Core Dump总结

    Core Dump总结 查看现在系统dump core的情况 ulimit -c 结果表示core文件的大小.如果显示0,则不会dump core,显示unlimited不限制core文件大小 打开d ...

  8. Linux的命名空间

    1. 为什么提供命名空间 命名空间是一种轻量级的虚拟化手段. 传统的虚拟化软件,是虚拟化多个不同的操作系统,对共享资源的限制很大. 通过提供命名空间,可以让进程与进程之间,用户与用户之间彼此看不到对方 ...

  9. HDU 6693 Valentine's Day (概率)

    2019 杭电多校 10 1003 题目链接:HDU 6693 比赛链接:2019 Multi-University Training Contest 10 Problem Description O ...

  10. java IO 类概述表

    列举常用的类方便查看,温故知新! byte input byte output character input character output Basic InputStream OutputStr ...