Educational Codeforces Round 22

居然水了一天时间才做完这套题。。。

A. The Contest
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Pasha is participating in a contest on one well-known website. This time he wants to win the contest and will do anything to get to the first place!

This contest consists of n problems, and Pasha solves ith problem in ai time units (his solutions are always correct). At any moment of time he can be thinking about a solution to only one of the problems (that is, he cannot be solving two problems at the same time). The time Pasha spends to send his solutions is negligible. Pasha can send any number of solutions at the same moment.

Unfortunately, there are too many participants, and the website is not always working. Pasha received the information that the website will be working only during m time periods, jth period is represented by its starting moment lj and ending moment rj. Of course, Pasha can send his solution only when the website is working. In other words, Pasha can send his solution at some moment T iff there exists a period x such that lx ≤ T ≤ rx.

Pasha wants to know his best possible result. We need to tell him the minimal moment of time by which he is able to have solutions to all problems submitted, if he acts optimally, or say that it's impossible no matter how Pasha solves the problems.

Input

The first line contains one integer n (1 ≤ n ≤ 1000) — the number of problems. The second line contains n integers ai (1 ≤ ai ≤ 105) — the time Pasha needs to solve ith problem.

The third line contains one integer m (0 ≤ m ≤ 1000) — the number of periods of time when the website is working. Next m lines represent these periods. jth line contains two numbers lj and rj (1 ≤ lj < rj ≤ 105) — the starting and the ending moment of jth period.

It is guaranteed that the periods are not intersecting and are given in chronological order, so for every j > 1 the condition lj > rj - 1 is met.

Output

If Pasha can solve and submit all the problems before the end of the contest, print the minimal moment of time by which he can have all the solutions submitted.

Otherwise print "-1" (without brackets).

Examples
input
2
3 4
2
1 4
7 9
output
7
input
1
5
1
1 4
output
-1
input
1
5
1
1 5
output
5
Note

In the first example Pasha can act like this: he solves the second problem in 4 units of time and sends it immediately. Then he spends 3 time units to solve the first problem and sends it 7 time units after the contest starts, because at this moment the website starts working again.

In the second example Pasha invents the solution only after the website stops working for the last time.

In the third example Pasha sends the solution exactly at the end of the first period.

显然就是做完之后第一个能交的时间点

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <map>
 9 #include <stack>
10 #include <set>
11 #include <vector>
12 #include <queue>
13 #include <time.h>
14 #define eps 1e-7
15 #define INF 0x3f3f3f3f
16 #define MOD 1000000007
17 #define rep0(j,n) for(int j=0;j<n;++j)
18 #define rep1(j,n) for(int j=1;j<=n;++j)
19 #define pb push_back
20 #define set0(n) memset(n,0,sizeof(n))
21 #define ll long long
22 #define ull unsigned long long
23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
24 #define max(a,b) (a>b?a:b)
25 #define min(a,b) (a<b?a:b)
26 #define print_runtime printf("Running time:%.3lfs
",double(clock())/1000.0)
27 #define TO(j) printf(#j": %d
",j);
28 //#define OJ
29 using namespace std;
30 const int MAXINT = 100010;
31 const int MAXNODE = 100010;
32 const int MAXEDGE = 2*MAXNODE;
33 char BUF,*buf;
34 int read(){
35     char c=getchar();int f=1,x=0;
36     while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
37     while(isdigit(c)){x=x*10+c-'0';c=getchar();}
38     return f*x;
39 }
40 char get_ch(){
41     char c=getchar();
42     while(!isalpha(c)) c=getchar();
43     return c;
44 }
45 //------------------- Head Files ----------------------//
46 
47 int n,m;
48 void get_input();
49 void work();
50 int main() {
51     get_input();
52     work();
53     return 0;
54 }
55 void work(){
56 
57 }
58 void get_input(){
59     int sum=0,l,r;
60     n=read();
61     rep0(i,n) sum+=read();
62     m=read();
63     rep0(i,m){
64         l=read();r=read();
65         if(sum<=r) {
66             printf("%d
",max(l,sum));
67             return ;
68         }
69     }
70     printf("-1
");
71 }
B. The Golden Age
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Unlucky year in Berland is such a year that its number n can be represented as n = xa + yb, where a and b are non-negative integer numbers.

For example, if x = 2 and y = 3 then the years 4 and 17 are unlucky (4 = 20 + 31, 17 = 23 + 32 = 24 + 30) and year 18 isn't unlucky as there is no such representation for it.

Such interval of years that there are no unlucky years in it is called The Golden Age.

You should write a program which will find maximum length of The Golden Age which starts no earlier than the year l and ends no later than the year r. If all years in the interval [l, r] are unlucky then the answer is 0.

Input

The first line contains four integer numbers xyl and r (2 ≤ x, y ≤ 1018, 1 ≤ l ≤ r ≤ 1018).

Output

Print the maximum length of The Golden Age within the interval [l, r].

If all years in the interval [l, r] are unlucky then print 0.

Examples
input
2 3 1 10
output
1
input
3 5 10 22
output
8
input
2 3 3 5
output
0
Note

In the first example the unlucky years are 2, 3, 4, 5, 7, 9 and 10. So maximum length of The Golden Age is achived in the intervals [1, 1], [6, 6] and [8, 8].

In the second example the longest Golden Age is the interval [15, 22].

 B:有趣

你发现 $ a^x $ 这个东西增长的非常快,枚举x是log的,枚举y也是log的,枚举所有合法的 $ a^x+b^y $ 就是 $ log^2 $ 的,都求出来以后排个序扫一下就好了,注意边界和乘法溢出的问题

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <map>
 9 #include <stack>
10 #include <set>
11 #include <vector>
12 #include <queue>
13 #include <time.h>
14 #define eps 1e-7
15 #define INF 0x3f3f3f3f
16 #define MOD 1000000007
17 #define rep0(j,n) for(int j=0;j<n;++j)
18 #define rep1(j,n) for(int j=1;j<=n;++j)
19 #define pb push_back
20 #define set0(n) memset(n,0,sizeof(n))
21 #define ll long long
22 #define ull unsigned long long
23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
24 #define max(a,b) (a>b?a:b)
25 #define min(a,b) (a<b?a:b)
26 #define print_runtime printf("Running time:%.3lfs
",double(clock())/1000.0)
27 #define TO(j) printf(#j": %d
",j);
28 //#define OJ
29 using namespace std;
30 const int MAXINT = 100010;
31 const int MAXNODE = 100010;
32 const int MAXEDGE = 2 * MAXNODE;
33 char BUF, *buf;
34 ull read() {
35     char c = getchar(); ull x = 0;
36     while (!isdigit(c)) { c = getchar(); }
37     while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
38     return x;
39 }
40 char get_ch() {
41     char c = getchar();
42     while (!isalpha(c)) c = getchar();
43     return c;
44 }
45 //------------------- Head Files ----------------------//
46 const ull UPPER_BOUND = (1ull << 62) - 1;
47 ull x, y, l, r, ax[300], by[300], unlucky[100000];
48 int cnt_a, cnt_b, cnt;
49 int overflow(ull a, ull b) {
50     return UPPER_BOUND / a < b;
51 }
52 void get_input();
53 void work();
54 int main() {
55     get_input();
56     work();
57     return 0;
58 }
59 void work() {
60     ull ans = 0, a = 1, b = 1;
61     while (1) {
62         ax[cnt_a++] = a;
63         if (!overflow(a, x) && a * x <= r) a = a * x; else break;
64     }
65     while (1) {
66         by[cnt_b++] = b;
67         if (!overflow(b, y) && b * y <= r) b = b * y; else break;
68     }
69     rep0(i, cnt_a) rep0(j, cnt_b) unlucky[cnt++] = ax[i] + by[j];
70     unlucky[cnt++] = l - 1; unlucky[cnt++] = r + 1;
71     sort(unlucky, unlucky + cnt);
72     cnt = unique(unlucky, unlucky + cnt) - unlucky;
73     for (int i = 1; i<cnt&&unlucky[i] <= r + 1; i++) if(unlucky[i]>=l) ans = max(ans, unlucky[i] - unlucky[i - 1] - 1);
74     printf("%llu
", ans);
75 }
76 void get_input() {
77     x = read(); y = read(); l = read(); r = read();
78 }
C. The Tag Game
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Alice got tired of playing the tag game by the usual rules so she offered Bob a little modification to it. Now the game should be played on an undirected rooted tree of n vertices. Vertex 1 is the root of the tree.

Alice starts at vertex 1 and Bob starts at vertex x (x ≠ 1). The moves are made in turns, Bob goes first. In one move one can either stay at the current vertex or travel to the neighbouring one.

The game ends when Alice goes to the same vertex where Bob is standing. Alice wants to minimize the total number of moves and Bob wants to maximize it.

You should write a program which will determine how many moves will the game last.

Input

The first line contains two integer numbers n and x (2 ≤ n ≤ 2·105, 2 ≤ x ≤ n).

Each of the next n - 1 lines contains two integer numbers a and b (1 ≤ a, b ≤ n) — edges of the tree. It is guaranteed that the edges form a valid tree.

Output

Print the total number of moves Alice and Bob will make.

Examples
input
4 3
1 2
2 3
2 4
output
4
input
5 2
1 2
2 3
3 4
2 5
output
6
Note

In the first example the tree looks like this:

The red vertex is Alice's starting position, the blue one is Bob's. Bob will make the game run the longest by standing at the vertex 3during all the game. So here are the moves:

B: stay at vertex 3

A: go to vertex 2

B: stay at vertex 3

A: go to vertex 3

In the second example the tree looks like this:

The moves in the optimal strategy are:

B: go to vertex 3

A: go to vertex 2

B: go to vertex 4

A: go to vertex 3

B: stay at vertex 4

A: go to vertex 4

C:没啥好说的吧,最后的操作肯定是一个人一直往下追,另一个人往上爬一点以后开始向下跑,一遍dfs,注意由于最后一步肯定是追的人动,答案只要乘2即可

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <map>
 9 #include <stack>
10 #include <set>
11 #include <vector>
12 #include <queue>
13 #include <time.h>
14 #define eps 1e-7
15 #define INF 0x3f3f3f3f
16 #define MOD 1000000007
17 #define rep0(j,n) for(int j=0;j<n;++j)
18 #define rep1(j,n) for(int j=1;j<=n;++j)
19 #define pb push_back
20 #define set0(n) memset(n,0,sizeof(n))
21 #define ll long long
22 #define ull unsigned long long
23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
24 #define max(a,b) (a>b?a:b)
25 #define min(a,b) (a<b?a:b)
26 #define print_runtime printf("Running time:%.3lfs
",double(clock())/1000.0)
27 #define TO(j) printf(#j": %d
",j);
28 //#define OJ
29 using namespace std;
30 const int MAXINT = 100010;
31 const int MAXNODE = 200010;
32 const int MAXEDGE = 2 * MAXNODE;
33 char BUF, *buf;
34 int read() {
35     char c = getchar(); int f = 1, x = 0;
36     while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
37     while (isdigit(c)) {x = x * 10 + c - '0'; c = getchar();}
38     return f * x;
39 }
40 char get_ch() {
41     char c = getchar();
42     while (!isalpha(c)) c = getchar();
43     return c;
44 }
45 //------------------- Head Files ----------------------//
46 struct edge {
47     int u, v;
48     edge *nxt;
49     edge() {}
50     edge(int _u, int _v, edge *_nxt): u(_u), v(_v), nxt(_nxt) {}
51 } mp[MAXEDGE], *head[MAXNODE];
52 int cnt,dep[MAXNODE],down[MAXNODE],n,x,fa[MAXNODE];
53 void addedge(int u, int v) {
54     mp[cnt] = edge(u, v, head[u]);
55     head[u] = &mp[cnt++];
56     mp[cnt] = edge (v, u, head[v]);
57     head[v] = &mp[cnt++];
58 }
59 void dfs(int p){
60     down[p]=1;
61     iter(i,p){
62         if(i->v==fa[p]) continue;
63         dep[i->v]=dep[p]+1;
64         fa[i->v]=p;
65         dfs(i->v);
66         down[p]=max(down[p],down[i->v]+1);
67     }
68 }
69 void get_input();
70 void work();
71 int main() {
72     get_input();
73     work();
74     return 0;
75 }
76 void work() {
77     int ans=0;
78     dfs(1);
79     int p=x;
80     while(dep[x]-dep[p]<dep[p]-dep[1]){
81         ans=max(ans,dep[p]+down[p]-1);
82         p=fa[p];
83     }
84     printf("%d
",ans*2);
85 }
86 void get_input() {
87     n=read();x=read();
88     rep0(i,n-1){
89         int u=read(),v=read();
90         addedge(u,v);
91     }
92 }
D. Two Melodies
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Alice is a beginner composer and now she is ready to create another masterpiece. And not even the single one but two at the same time!

Alice has a sheet with n notes written on it. She wants to take two such non-empty non-intersecting subsequences that both of them form a melody and sum of their lengths is maximal.

Subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.

Subsequence forms a melody when each two adjacent notes either differs by 1 or are congruent modulo 7.

You should write a program which will calculate maximum sum of lengths of such two non-empty non-intersecting subsequences that both of them form a melody.

Input

The first line contains one integer number n (2 ≤ n ≤ 5000).

The second line contains n integer numbers a1, a2, ..., an (1 ≤ ai ≤ 105) — notes written on a sheet.

Output

Print maximum sum of lengths of such two non-empty non-intersecting subsequences that both of them form a melody.

Examples
input
4
1 2 4 5
output
4
input
6
62 22 60 61 48 49
output
5
Note

In the first example subsequences [1, 2] and [4, 5] give length 4 in total.

In the second example subsequences [62, 48, 49] and [60, 61] give length 5 in total. If you choose subsequence [62, 61] in the first place then the second melody will have maximum length 2, that gives the result of 4, which is not maximal.

D:这大概是最难的一道题,很明显是个n^2dp,但是不知道怎么处理相交的问题

正确做法是只允许本来较后面的一个端点进行转移,这样就可以避免相交

维护前缀信息去掉一个n即可

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <map>
 9 #include <stack>
10 #include <set>
11 #include <vector>
12 #include <queue>
13 #include <time.h>
14 #define eps 1e-7
15 #define INF 0x3f3f3f3f
16 #define MOD 1000000007
17 #define rep0(j,n) for(int j=0;j<n;++j)
18 #define rep1(j,n) for(int j=1;j<=n;++j)
19 #define pb push_back
20 #define set0(n) memset(n,0,sizeof(n))
21 #define ll long long
22 #define ull unsigned long long
23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
24 #define print_runtime printf("Running time:%.3lfs
",double(clock())/1000.0)
25 #define TO(j) printf(#j": %d
",j);
26 //#define OJ
27 using namespace std;
28 const int MAXINT = 100010;
29 const int MAXNODE = 100010;
30 const int MAXEDGE = 2 * MAXNODE;
31 char BUF, *buf;
32 int read() {
33     char c = getchar(); int f = 1, x = 0;
34     while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
35     while (isdigit(c)) {x = x * 10 + c - '0'; c = getchar();}
36     return f * x;
37 }
38 char get_ch() {
39     char c = getchar();
40     while (!isalpha(c)) c = getchar();
41     return c;
42 }
43 //------------------- Head Files ----------------------//
44 
45 int dp[5010][5010], n, a[5010], mx_s[7],mx_v[100010];
46 void get_input();
47 void work();
48 int main() {
49     get_input();
50     work();
51     return 0;
52 }
53 void work() {
54     int ans=0;
55     for(int j=0;j<=n;j++){
56         for(int i=0;i<=n;i++){
57             if(i==j) dp[i][j]=0; 
58             else if(i<j) dp[i][j]=dp[j][i];
59             else dp[i][j] = max(max(mx_s[a[i]%7],dp[j][0]),max(mx_v[a[i]+1],mx_v[a[i]-1]))+1;
60             ans = max(ans,dp[i][j]);
61             mx_s[a[i]%7] = max(mx_s[a[i]%7],dp[i][j]);
62             mx_v[a[i]]=max(mx_v[a[i]],dp[i][j]);
63         }
64         memset(mx_s,0,sizeof(mx_s));
65         for(int i=0;i<=n;i++) mx_v[a[i]]=0;
66     }
67     printf("%d
",ans);
68 }
69 void get_input() {
70     n = read();
71     rep1(i, n) a[i] = read();
72 }
E. Army Creation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

As you might remember from our previous rounds, Vova really likes computer games. Now he is playing a strategy game known as Rage of Empires.

In the game Vova can hire n different warriors; ith warrior has the type ai. Vova wants to create a balanced army hiring some subset of warriors. An army is called balanced if for each type of warrior present in the game there are not more than k warriors of this type in the army. Of course, Vova wants his army to be as large as possible.

To make things more complicated, Vova has to consider q different plans of creating his army. ith plan allows him to hire only warriors whose numbers are not less than li and not greater than ri.

Help Vova to determine the largest size of a balanced army for each plan.

Be aware that the plans are given in a modified way. See input section for details.

Input

The first line contains two integers n and k (1 ≤ n, k ≤ 100000).

The second line contains n integers a1, a2, ... an (1 ≤ ai ≤ 100000).

The third line contains one integer q (1 ≤ q ≤ 100000).

Then q lines follow. ith line contains two numbers xi and yi which represent ith plan (1 ≤ xi, yi ≤ n).

You have to keep track of the answer to the last plan (let's call it last). In the beginning last = 0. Then to restore values of li and ri for the ith plan, you have to do the following:

  1. li = ((xi + lastmod n) + 1;
  2. ri = ((yi + lastmod n) + 1;
  3. If li > ri, swap li and ri.
Output

Print q numbers. ith number must be equal to the maximum size of a balanced army when considering ith plan.

Example
input
6 2
1 1 1 2 2 2
5
1 6
4 3
1 1
2 6
2 6
output
2
4
1
3
2
Note

In the first example the real plans are:

  1. 1 2
  2. 1 6
  3. 6 6
  4. 2 4
  5. 4 6

E:这不就是区间颜色个的变种数么,直接上莫。。

嘿呀,CF你学坏了呀你,开始出强制在线题了

那分块咯,预处理出到每个块结尾的数组个数和块与块之间的答案

注意一下开闭区间,调了半天

正解是没看懂

UPD1 哦,看懂了,把原来的区间颜色个数拓展一下

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <string>
  6 #include <cstring>
  7 #include <cmath>
  8 #include <map>
  9 #include <stack>
 10 #include <set>
 11 #include <vector>
 12 #include <queue>
 13 #include <time.h>
 14 #define eps 1e-7
 15 #define INF 0x3f3f3f3f
 16 #define MOD 1000000007
 17 #define rep0(j,n) for(int j=0;j<n;++j)
 18 #define rep1(j,n) for(int j=1;j<=n;++j)
 19 #define pb push_back
 20 #define set0(n) memset(n,0,sizeof(n))
 21 #define ll long long
 22 #define ull unsigned long long
 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
 24 #define max(a,b) (a>b?a:b)
 25 #define min(a,b) (a<b?a:b)
 26 #define print_runtime printf("Running time:%.3lfs
",double(clock())/1000.0)
 27 #define TO(j) printf(#j": %d
",j);
 28 //#define OJ
 29 using namespace std;
 30 const int MAXINT = 100010;
 31 const int MAXBLOCK = 320;
 32 const int MAXNODE = 100010;
 33 const int MAXEDGE = 2 * MAXNODE;
 34 char BUF, *buf;
 35 int read() {
 36     char c = getchar(); int f = 1, x = 0;
 37     while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); }
 38     while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
 39     return f * x;
 40 }
 41 char get_ch() {
 42     char c = getchar();
 43     while (!isalpha(c)) c = getchar();
 44     return c;
 45 }
 46 //------------------- Head Files ----------------------//
 47 
 48 int cnt[320][MAXINT], ans[320][320], lb[320], rb[320], cnt_b, bl[MAXINT], n, k, a[MAXINT], cnt_t[MAXINT];
 49 int calc(int l, int r) {
 50     int ret = 0;
 51     if (r - l <= 2 * MAXBLOCK) {
 52         for (int i = l; i <= r; i++) {
 53             cnt_t[a[i]]++;
 54             if (cnt_t[a[i]] <= k) ret++;
 55         }
 56         for (int i = l; i <= r; i++) cnt_t[a[i]]--;
 57         return ret;
 58     }
 59     int block_l = bl[l] + 1;
 60     int block_r = bl[r] - 1;
 61     ret = ans[block_l][block_r];
 62     for (int i = l; i <= rb[block_l-1]; i++) {
 63         if (cnt_t[a[i]] == 0) cnt_t[a[i]] = cnt[block_r][a[i]] - cnt[block_l-1][a[i]];
 64         cnt_t[a[i]]++;
 65         if (cnt_t[a[i]] <= k) ret++;
 66     }
 67     for (int i = lb[block_r+1]; i <= r; i++) {
 68         if (cnt_t[a[i]] == 0) cnt_t[a[i]] = cnt[block_r][a[i]] - cnt[block_l-1][a[i]];
 69         cnt_t[a[i]]++;
 70         if (cnt_t[a[i]] <= k) ret++;
 71     }
 72     for (int i = l; i <= rb[block_l-1]; i++) cnt_t[a[i]] = 0;
 73     for (int i = lb[block_r+1]; i <= r; i++) cnt_t[a[i]] = 0;
 74     return ret;
 75 }
 76 void get_input();
 77 void work();
 78 int main() {
 79     get_input();
 80     work();
 81     return 0;
 82 }
 83 void work() {
 84     rep1(i, n) {
 85         bl[i] = i / MAXBLOCK;
 86         if (!lb[i / MAXBLOCK]) lb[i / MAXBLOCK] = i;
 87         rb[i / MAXBLOCK] = i;
 88         if (bl[i] != bl[i - 1]) rep1(j, 100000) cnt[bl[i]][j] = cnt[bl[i - 1]][j];
 89         cnt[bl[i]][a[i]]++;
 90     }
 91     cnt_b = (n - 1) / MAXBLOCK + 1;
 92     rep0(i, cnt_b) {
 93         int cnt_a = 0;
 94         memset(cnt_t, 0, sizeof(cnt_t));
 95         for (int j = i; j < cnt_b; j++) {
 96             for (int l = lb[j]; l <= rb[j]; l++) {
 97                 cnt_t[a[l]]++;
 98                 if (cnt_t[a[l]] <= k) cnt_a++;
 99             }
100             ans[i][j] = cnt_a;
101         }
102     }
103     memset(cnt_t, 0, sizeof(cnt_t));
104     int q = read(), last = 0;
105     while (q--) {
106         int l = read(), r = read();
107         l=(l+last)%n+1;
108         r=(r+last)%n+1;
109         if(l>r) swap(l,r);
110         last = calc(l, r);
111         printf("%d
", last);
112     }
113 }
114 void get_input() {
115     n = read(); k = read();
116     rep1(i, n) a[i] = read();
117 }
F. Bipartite Checking
time limit per test
6 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given an undirected graph consisting of n vertices. Initially there are no edges in the graph. Also you are given q queries, each query either adds one undirected edge to the graph or removes it. After each query you have to check if the resulting graph is bipartite (that is, you can paint all vertices of the graph into two colors so that there is no edge connecting two vertices of the same color).

Input

The first line contains two integers n and q (2 ≤ n, q ≤ 100000).

Then q lines follow. ith line contains two numbers xi and yi (1 ≤ xi < yi ≤ n). These numbers describe ith query: if there is an edge between vertices xi and yi, then remove it, otherwise add it.

Output

Print q lines. ith line must contain YES if the graph is bipartite after ith query, and NO otherwise.

Example
input
3 5
2 3
1 3
1 2
1 2
1 2
output
YES
YES
NO
YES
NO

F:带删边加边的二分图判定

对时间分治不难写,倒是这个坑爹的并查集弄了我半天

需要额外维护一个信息,表示这个点到他父亲在图上的距离的奇偶性

我感觉我还是写的挺好看的,cdq分治的写法确实漂亮

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <string>
  6 #include <cstring>
  7 #include <cmath>
  8 #include <map>
  9 #include <stack>
 10 #include <set>
 11 #include <vector>
 12 #include <queue>
 13 #include <time.h>
 14 #define eps 1e-7
 15 #define INF 0x3f3f3f3f
 16 #define MOD 1000000007
 17 #define rep0(j,n) for(int j=0;j<n;++j)
 18 #define rep1(j,n) for(int j=1;j<=n;++j)
 19 #define pb push_back
 20 #define set0(n) memset(n,0,sizeof(n))
 21 #define ll long long
 22 #define ull unsigned long long
 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
 24 #define max(a,b) (a>b?a:b)
 25 #define min(a,b) (a<b?a:b)
 26 #define print_runtime printf("Running time:%.3lfs
",double(clock())/1000.0)
 27 #define TO(j) printf(#j": %d
",j);
 28 //#define OJ
 29 using namespace std;
 30 const int MAXINT = 100010;
 31 const int MAXNODE = 100010;
 32 const int MAXEDGE = 2 * MAXNODE;
 33 char BUF, *buf;
 34 int read() {
 35     char c = getchar(); int f = 1, x = 0;
 36     while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); }
 37     while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
 38     return f*x;
 39 }
 40 char get_ch() {
 41     char c = getchar();
 42     while (!isalpha(c)) c = getchar();
 43     return c;
 44 }
 45 //------------------- Head Files ----------------------//
 46 
 47 struct edge {
 48     int l, r, u, v;
 49     edge(int _u, int _v, int _l, int _r) :u(_u), v(_v), l(_l), r(_r) {}
 50     edge() {}
 51 };
 52 pair<int, int> op[MAXINT];
 53 int top, sz[MAXINT], fa[MAXINT], len[MAXINT];
 54 vector<edge> e;
 55 map<pair<int, int>, int> hs;
 56 int q, ans[MAXINT], n;
 57 void recover(int bot) {
 58     while (top != bot) {
 59         top--;
 60         sz[fa[op[top].first]] = op[top].second;
 61         fa[op[top].first] = op[top].first;
 62         len[op[top].first] = 0;
 63     }
 64 }
 65 pair<int, int> findfa(int p) {
 66     int d = 0;
 67     while (p != fa[p]) {
 68         d += len[p];
 69         p = fa[p];
 70     }
 71     return make_pair(p, d);
 72 }
 73 int merge(int u, int v) {
 74     pair<int, int> ru, rv;
 75     ru = findfa(u); rv = findfa(v);
 76     if (ru.first == rv.first && (ru.second & 1) == (rv.second & 1)) return -1;
 77     if (sz[ru.first]>sz[rv.first]) {
 78         fa[rv.first] = ru.first;
 79         len[rv.first] = rv.second + ru.second + 1;
 80         op[top++] = make_pair(rv.first, sz[ru.first]);
 81         sz[ru.first] += sz[rv.first];
 82     }
 83     else {
 84         fa[ru.first] = rv.first;
 85         len[ru.first] = rv.second + ru.second + 1;
 86         op[top++] = make_pair(ru.first, sz[rv.first]);
 87         sz[rv.first] += sz[ru.first];
 88     }
 89     return 0;
 90 }
 91 void divide(int l, int r, vector<edge> act) {
 92     int bot = top, mid = (l + r) / 2;
 93     vector<edge> la, ra;
 94     for (auto i = act.begin(); i != act.end(); i++) {
 95         if (i->l <= l&&i->r >= r) {
 96             if (merge(i->u, i->v) == -1) {
 97                 for (int i = l; i<r; i++) ans[i] = 0;
 98                 recover(bot);
 99                 return;
100             }
101             continue;
102         }
103         if (i->l<mid) la.push_back(*i);
104         if (i->r>mid) ra.push_back(*i);
105     }
106     if (r - l>1) {
107         divide(l, mid, la);
108         divide(mid, r, ra);
109     }
110     recover(bot);
111 }
112 void get_input();
113 void work();
114 int main() {
115     get_input();
116     work();
117     return 0;
118 }
119 void work() {
120     fill(ans, ans + q, 1);
121     divide(0, q, e);
122     rep0(i, q) printf(ans[i] ? "YES
" : "NO
");
123 }
124 void get_input() {
125     n = read(); q = read();
126     rep1(i, n) fa[i] = i, sz[i] = 1;
127     rep0(i, q) {
128         int u = read(), v = read();
129         if (u>v) swap(u, v);
130         if (hs.count(make_pair(u, v))) {
131             e.push_back(edge(u, v, hs[make_pair(u, v)], i));
132             hs.erase(hs.find(make_pair(u, v)));
133         }
134         else {
135             hs[make_pair(u, v)] = i;
136         }
137     }
138     for (auto i = hs.begin(); i != hs.end(); i++) {
139         e.push_back(edge(i->first.first, i->first.second, i->second, q));
140     }
141 }
原文地址:https://www.cnblogs.com/LoveYayoi/p/6953039.html